diff options
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 125 |
1 files changed, 103 insertions, 22 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 9e879940a9..95f41f315a 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3,20 +3,20 @@ * Copyright (c) 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -343,9 +343,18 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ } s->internal_buffer_count++; - if(s->pkt) pic->pkt_pts= s->pkt->pts; - else pic->pkt_pts= AV_NOPTS_VALUE; + if (s->pkt) { + pic->pkt_pts = s->pkt->pts; + pic->pkt_pos = s->pkt->pos; + } else { + pic->pkt_pts = AV_NOPTS_VALUE; + pic->pkt_pos = -1; + } pic->reordered_opaque= s->reordered_opaque; + pic->sample_aspect_ratio = s->sample_aspect_ratio; + pic->width = s->width; + pic->height = s->height; + pic->format = s->pix_fmt; if(s->debug&FF_DEBUG_BUFFERS) av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count); @@ -360,6 +369,7 @@ void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ assert(pic->type==FF_BUFFER_TYPE_INTERNAL); assert(s->internal_buffer_count); + if(s->internal_buffer){ buf = NULL; /* avoids warning */ for(i=0; i<s->internal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize buf= &((InternalBuffer*)s->internal_buffer)[i]; @@ -371,6 +381,7 @@ void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; FFSWAP(InternalBuffer, *buf, *last); + } for(i=0; i<4; i++){ pic->data[i]=NULL; @@ -447,8 +458,11 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum void avcodec_get_frame_defaults(AVFrame *pic){ memset(pic, 0, sizeof(AVFrame)); - pic->pts= AV_NOPTS_VALUE; + pic->pts = pic->best_effort_timestamp = AV_NOPTS_VALUE; + pic->pkt_pos = -1; pic->key_frame= 1; + pic->sample_aspect_ratio = (AVRational){0, 1}; + pic->format = -1; /* unknown */ } AVFrame *avcodec_alloc_frame(void){ @@ -461,6 +475,12 @@ AVFrame *avcodec_alloc_frame(void){ return pic; } +static void avcodec_get_subtitle_defaults(AVSubtitle *sub) +{ + memset(sub, 0, sizeof(*sub)); + sub->pts = AV_NOPTS_VALUE; +} + int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) { int ret = 0; @@ -543,7 +563,7 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) } } - if (avctx->codec->max_lowres < avctx->lowres) { + if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) { av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n", avctx->codec->max_lowres); ret = AVERROR(EINVAL); @@ -596,12 +616,19 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) } } + avctx->pts_correction_num_faulty_pts = + avctx->pts_correction_num_faulty_dts = 0; + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + if(avctx->codec->init && !(avctx->active_thread_type&FF_THREAD_FRAME)){ ret = avctx->codec->init(avctx); if (ret < 0) { goto free_and_end; } } + + ret=0; end: entangled_thread_counter--; @@ -658,13 +685,44 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); return -1; } - if(sub->num_rects == 0 || !sub->rects) - return -1; + ret = avctx->codec->encode(avctx, buf, buf_size, sub); avctx->frame_number++; return ret; } +/** + * Attempt to guess proper monotonic timestamps for decoded video frames + * which might have incorrect times. Input timestamps may wrap around, in + * which case the output will as well. + * + * @param pts the pts field of the decoded AVPacket, as passed through + * AVFrame.pkt_pts + * @param dts the dts field of the decoded AVPacket + * @return one of the input values, may be AV_NOPTS_VALUE + */ +static int64_t guess_correct_pts(AVCodecContext *ctx, + int64_t reordered_pts, int64_t dts) +{ + int64_t pts = AV_NOPTS_VALUE; + + if (dts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; + ctx->pts_correction_last_dts = dts; + } + if (reordered_pts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; + ctx->pts_correction_last_pts = reordered_pts; + } + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) + && reordered_pts != AV_NOPTS_VALUE) + pts = reordered_pts; + else + pts = dts; + + return pts; +} + int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) @@ -675,9 +733,9 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi if((avctx->coded_width||avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) return -1; - avctx->pkt = avpkt; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ + av_packet_split_side_data(avpkt); + avctx->pkt = avpkt; if (HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, avpkt); @@ -685,12 +743,30 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi ret = avctx->codec->decode(avctx, picture, got_picture_ptr, avpkt); picture->pkt_dts= avpkt->dts; + + if(!avctx->has_b_frames){ + picture->pkt_pos= avpkt->pos; + } + //FIXME these should be under if(!avctx->has_b_frames) + if (!picture->sample_aspect_ratio.num) + picture->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (!picture->width) + picture->width = avctx->width; + if (!picture->height) + picture->height = avctx->height; + if (picture->format == PIX_FMT_NONE) + picture->format = avctx->pix_fmt; } emms_c(); //needed to avoid an emms_c() call before every return; - if (*got_picture_ptr) + + if (*got_picture_ptr){ avctx->frame_number++; + picture->best_effort_timestamp = guess_correct_pts(avctx, + picture->pkt_pts, + picture->pkt_dts); + } }else ret= 0; @@ -734,6 +810,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, avctx->pkt = avpkt; *got_sub_ptr = 0; + avcodec_get_subtitle_defaults(sub); ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); if (*got_sub_ptr) avctx->frame_number++; @@ -827,14 +904,18 @@ AVCodec *avcodec_find_encoder_by_name(const char *name) AVCodec *avcodec_find_decoder(enum CodecID id) { - AVCodec *p; + AVCodec *p, *experimental=NULL; p = first_avcodec; while (p) { - if (p->decode != NULL && p->id == id) - return p; + if (p->decode != NULL && p->id == id) { + if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { + experimental = p; + } else + return p; + } p = p->next; } - return NULL; + return experimental; } AVCodec *avcodec_find_decoder_by_name(const char *name) @@ -1025,13 +1106,13 @@ unsigned avcodec_version( void ) const char *avcodec_configuration(void) { - return LIBAV_CONFIGURATION; + return FFMPEG_CONFIGURATION; } const char *avcodec_license(void) { #define LICENSE_PREFIX "libavcodec license: " - return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1; + return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; } void avcodec_init(void) @@ -1158,7 +1239,7 @@ int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b){ void av_log_missing_feature(void *avc, const char *feature, int want_sample) { - av_log(avc, AV_LOG_WARNING, "%s not implemented. Update your Libav " + av_log(avc, AV_LOG_WARNING, "%s not implemented. Update your FFmpeg " "version to the newest one from Git. If the problem still " "occurs, it means that your file has a feature which has not " "been implemented.\n", feature); @@ -1175,8 +1256,8 @@ void av_log_ask_for_sample(void *avc, const char *msg, ...) if (msg) av_vlog(avc, AV_LOG_WARNING, msg, argument_list); av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample " - "of this file to ftp://upload.libav.org/incoming/ " - "and contact the libav-devel mailing list.\n"); + "of this file to ftp://upload.ffmpeg.org/MPlayer/incoming/ " + "and contact the ffmpeg-devel mailing list.\n"); va_end(argument_list); } |