On Wed, 19 Sep 2012 18:53:12 -0400, Justin Ruggles <[email protected]> 
wrote:
> ---
>  avconv.c              |    4 ----
>  libavcodec/internal.h |   14 ++++++++++++++
>  libavcodec/utils.c    |   13 +++++++++++++
>  3 files changed, 27 insertions(+), 4 deletions(-)
> 
> diff --git a/avconv.c b/avconv.c
> index acb4994..0fb483a 100644
> --- a/avconv.c
> +++ b/avconv.c
> @@ -1086,10 +1086,6 @@ static int decode_audio(InputStream *ist, AVPacket 
> *pkt, int *got_output)
>      if (decoded_frame->pts != AV_NOPTS_VALUE)
>          ist->next_dts = av_rescale_q(decoded_frame->pts, avctx->time_base,
>                                       AV_TIME_BASE_Q);
> -    else if (pkt->pts != AV_NOPTS_VALUE) {
> -        decoded_frame->pts = pkt->pts;
> -        pkt->pts           = AV_NOPTS_VALUE;
> -    }
>      if (ist->next_dts != AV_NOPTS_VALUE)
>          ist->next_dts += av_rescale_q(decoded_frame->nb_samples, 
> avctx->time_base,
>                                        AV_TIME_BASE_Q);
> diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> index 0bfc924..d03c256 100644
> --- a/libavcodec/internal.h
> +++ b/libavcodec/internal.h
> @@ -76,6 +76,20 @@ typedef struct AVCodecInternal {
>       * padded with silence. Reject all subsequent frames.
>       */
>      int last_audio_frame;
> +
> +    /**
> +     * pts of the last packet passed to the decoder (audio only)
> +     * This is used to detect duplicate pts for timestamp interpolation.
> +     * It is reset to AV_NOPTS_VALUE on flush.
> +     */
> +    int64_t last_pts;
> +
> +    /**
> +     * Interpolated pts for the next decoded frame (audio only).
> +     * This is used when there are multiple frames per packet or duplicate 
> pts
> +     * in subsequent packets.
> +     */
> +    int64_t next_pts;
>  } AVCodecInternal;
>  
>  struct AVCodecDefault {
> diff --git a/libavcodec/utils.c b/libavcodec/utils.c
> index def614a..760e5c2 100644
> --- a/libavcodec/utils.c
> +++ b/libavcodec/utils.c
> @@ -672,6 +672,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext 
> *avctx, const AVCodec *code
>          ret = AVERROR(ENOMEM);
>          goto end;
>      }
> +    avctx->internal->last_pts = avctx->internal->next_pts = AV_NOPTS_VALUE;
>  
>      if (codec->priv_data_size > 0) {
>        if(!avctx->priv_data){
> @@ -1327,10 +1328,21 @@ int attribute_align_arg 
> avcodec_decode_audio4(AVCodecContext *avctx,
>      if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
>          ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt);
>          if (ret >= 0 && *got_frame_ptr) {
> +            AVCodecInternal *avci = avctx->internal;

nit: I'd put an empty line here

>              avctx->frame_number++;
>              frame->pkt_dts = avpkt->dts;
>              if (frame->format == AV_SAMPLE_FMT_NONE)
>                  frame->format = avctx->sample_fmt;

and here

> +            /* timestamp interpolation */
> +            if (frame->pts == AV_NOPTS_VALUE) {
> +                if (avpkt->pts == AV_NOPTS_VALUE || avci->last_pts == 
> avpkt->pts)
> +                    frame->pts = avci->next_pts;
> +                else
> +                    frame->pts = avpkt->pts;
> +            }
> +            if (frame->pts != AV_NOPTS_VALUE)
> +                avci->next_pts = frame->pts + frame->nb_samples;
> +            avci->last_pts = avpkt->pts;
>          }
>      }
>      return ret;
> @@ -1659,6 +1671,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
>          ff_thread_flush(avctx);
>      else if(avctx->codec->flush)
>          avctx->codec->flush(avctx);
> +    avctx->internal->last_pts = avctx->internal->next_pts = AV_NOPTS_VALUE;
>  }
>  
>  static void video_free_buffers(AVCodecContext *s)
> -- 
> 1.7.1

Otherwise LGTM.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to