Merge commit 'a8068346e48e123f8d3bdf4d64464d81e53e5fc7'
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>
Thu, 31 Mar 2016 20:19:49 +0000 (21:19 +0100)
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>
Thu, 31 Mar 2016 20:20:02 +0000 (21:20 +0100)
* commit 'a8068346e48e123f8d3bdf4d64464d81e53e5fc7':
  lavc: add a variant of av_get_audio_frame_duration working with AVCodecParameters

Fixes from jamrial incorporated.

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
1  2 
doc/APIchanges
libavcodec/avcodec.h
libavcodec/utils.c

diff --cc doc/APIchanges
@@@ -15,49 -13,19 +15,50 @@@ libavutil:     2015-08-2
  
  API changes, most recent first:
  
 -2016-xx-xx - lavc 57.14.0 - avcodec.h
 +2016-xx-xx - lavc 57.33.0 - avcodec.h
    xxxxxxx - Add AVCodecParameters and its related API.
+   xxxxxxx - Add av_get_audio_frame_duration2().
  
 -2016-xx-xx - xxxxxxx - lavf 57.4.0 - avformat.h
 -  Add AVFormatContext.protocol_whitelist and protocol_blacklist.
 -  Add 'protocol_whitelist' and 'protocol_blacklist' private options for
 -  avio_open2().
 -
 -2016-xx-xx - lavc 57.13.0 - avcodec.h
 +2016-03-11 - xxxxxxx - lavf/lavc 57.28.101
 +  Add requirement to bitstream filtering API that returned packets with
 +  size == 0 and side_data_elems == 0 are to be skipped by the caller.
 +
 +2016-XX-XX - xxxxxxx - lavf 57.28.100
 +  Add protocol blacklisting API
 +
 +2016-02-28 - xxxxxxx - lavc 57.27.101
 +  Validate AVFrame returned by get_buffer2 to have required
 +  planes not NULL and unused planes set to NULL as crashes
 +  and buffer overflow are possible with certain streams if
 +  that is not the case.
 +
 +2016-xx-xx - xxxxxxx - lavc 57.27.100 - avcodec.h
 +  "flags2" decoding option now allows the flag "ass_ro_flush_noop" preventing
 +  the reset of the ASS ReadOrder field on flush. This affects the content of
 +  AVSubtitles.rects[N]->ass when "sub_text_format" is set to "ass" (see
 +  previous entry).
 +
 +2016-xx-xx - xxxxxxx - lavc 57.26.100 - avcodec.h
 +  Add a "sub_text_format" subtitles decoding option allowing the values "ass"
 +  (recommended) and "ass_with_timings" (not recommended, deprecated, default).
 +  The default value for this option will change to "ass" at the next major
 +  libavcodec version bump.
 +
 +  The current default is "ass_with_timings" for compatibility. This means that
 +  all subtitles text decoders currently still output ASS with timings printed
 +  as strings in the AVSubtitles.rects[N]->ass fields.
 +
 +  Setting "sub_text_format" to "ass" allows a better timing accuracy (ASS
 +  timing is limited to a 1/100 time base, so this is relevant for any subtitles
 +  format needing a bigger one), ease timing adjustments, and prevents the need
 +  of removing the timing from the decoded string yourself. This form is also
 +  known as "the Matroska form". The timing information (start time, duration)
 +  can be found in the AVSubtitles fields.
 +
 +2016-xx-xx - lavc 57.25.0 - avcodec.h
    Add AVCodecContext.hw_frames_ctx.
  
 -2016-xx-xx - lavfi 6.2.0 - avfilter.h
 +2016-xx-xx - lavfi 6.36.0 - avfilter.h
    xxxxxxx avfilter.h - Add AVFilterLink.hw_frames_ctx.
    xxxxxxx buffersrc.h - Add AVBufferSrcParameters and functions for handling it.
  
Simple merge
@@@ -3145,21 -2037,15 +3145,16 @@@ int av_get_bits_per_sample(enum AVCodec
      }
  }
  
- int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
+ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba,
 -                                    uint32_t tag, int bits_per_coded_sample, int frame_bytes)
++                                    uint32_t tag, int bits_per_coded_sample, int64_t bitrate,
++                                    uint8_t * extradata, int frame_size, int frame_bytes)
  {
-     int id, sr, ch, ba, tag, bps;
-     id  = avctx->codec_id;
-     sr  = avctx->sample_rate;
-     ch  = avctx->channels;
-     ba  = avctx->block_align;
-     tag = avctx->codec_tag;
-     bps = av_get_exact_bits_per_sample(avctx->codec_id);
+     int bps = av_get_exact_bits_per_sample(id);
  
      /* codecs with an exact constant bits per sample */
 -    if (bps > 0 && ch > 0 && frame_bytes > 0)
 -        return (frame_bytes * 8) / (bps * ch);
 +    if (bps > 0 && ch > 0 && frame_bytes > 0 && ch < 32768 && bps < 32768)
 +        return (frame_bytes * 8LL) / (bps * ch);
-     bps = avctx->bits_per_coded_sample;
+     bps = bits_per_coded_sample;
  
      /* codecs with a fixed packet duration */
      switch (id) {
                  return (frame_bytes - 4) * 2 / ch;
              case AV_CODEC_ID_ADPCM_IMA_AMV:
                  return (frame_bytes - 8) * 2 / ch;
-                 if (avctx->extradata)
 +            case AV_CODEC_ID_ADPCM_THP:
 +            case AV_CODEC_ID_ADPCM_THP_LE:
++                if (extradata)
 +                    return frame_bytes * 14 / (8 * ch);
 +                break;
              case AV_CODEC_ID_ADPCM_XA:
                  return (frame_bytes / 128) * 224 / ch;
              case AV_CODEC_ID_INTERPLAY_DPCM:
              if (ba > 0) {
                  /* calc from frame_bytes, channels, and block_align */
                  int blocks = frame_bytes / ba;
-                 switch (avctx->codec_id) {
+                 switch (id) {
                  case AV_CODEC_ID_ADPCM_IMA_WAV:
 -                    return blocks * (1 + (ba - 4 * ch) / (4 * ch) * 8);
 +                    if (bps < 2 || bps > 5)
 +                        return 0;
 +                    return blocks * (1 + (ba - 4 * ch) / (bps * ch) * 8);
                  case AV_CODEC_ID_ADPCM_IMA_DK3:
                      return blocks * (((ba - 16) * 2 / 3 * 4) / ch);
                  case AV_CODEC_ID_ADPCM_IMA_DK4:
  
              if (bps > 0) {
                  /* calc from frame_bytes, channels, and bits_per_coded_sample */
-                 switch (avctx->codec_id) {
+                 switch (id) {
                  case AV_CODEC_ID_PCM_DVD:
 +                    if(bps<4)
 +                        return 0;
                      return 2 * (frame_bytes / ((bps * 2 / 8) * ch));
                  case AV_CODEC_ID_PCM_BLURAY:
 +                    if(bps<4)
 +                        return 0;
                      return frame_bytes / ((FFALIGN(ch, 2) * bps) / 8);
                  case AV_CODEC_ID_S302M:
                      return 2 * (frame_bytes / ((bps + 4) / 4)) / ch;
          }
      }
  
-     if (avctx->frame_size > 1 && frame_bytes)
-         return avctx->frame_size;
 +    /* Fall back on using frame_size */
-     if (avctx->bit_rate>0 && frame_bytes>0 && avctx->sample_rate>0 && avctx->block_align>1) {
-         if (avctx->codec_id == AV_CODEC_ID_WMAV1 || avctx->codec_id == AV_CODEC_ID_WMAV2)
-             return  (frame_bytes * 8LL * avctx->sample_rate) / avctx->bit_rate;
++    if (frame_size > 1 && frame_bytes)
++        return frame_size;
 +
 +    //For WMA we currently have no other means to calculate duration thus we
 +    //do it here by assuming CBR, which is true for all known cases.
++    if (bitrate > 0 && frame_bytes > 0 && sr > 0 && ba > 1) {
++        if (id == AV_CODEC_ID_WMAV1 || id == AV_CODEC_ID_WMAV2)
++            return  (frame_bytes * 8LL * sr) / bitrate;
 +    }
 +
      return 0;
  }
  
+ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
+ {
+     return get_audio_frame_duration(avctx->codec_id, avctx->sample_rate,
+                                     avctx->channels, avctx->block_align,
+                                     avctx->codec_tag, avctx->bits_per_coded_sample,
++                                    avctx->bit_rate, avctx->extradata, avctx->frame_size,
+                                     frame_bytes);
+ }
+ int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes)
+ {
+     return get_audio_frame_duration(par->codec_id, par->sample_rate,
+                                     par->channels, par->block_align,
+                                     par->codec_tag, par->bits_per_coded_sample,
++                                    par->bit_rate, par->extradata, par->frame_size,
+                                     frame_bytes);
+ }
  #if !HAVE_THREADS
  int ff_thread_init(AVCodecContext *s)
  {