Browse code

avcodec: add av_get_audio_frame_duration() function.

This is a utility function for the user to get the frame duration based on
the codec id, frame size in bytes, and various AVCodecContext parameters.

Justin Ruggles authored on 2012/01/27 10:08:23
Showing 4 changed files
... ...
@@ -12,6 +12,10 @@ libavutil:   2011-04-18
12 12
 
13 13
 API changes, most recent first:
14 14
 
15
+2012-xx-xx - lavc 54.8.0
16
+  xxxxxxx Add av_get_exact_bits_per_sample()
17
+  xxxxxxx Add av_get_audio_frame_duration()
18
+
15 19
 2012-03-xx - xxxxxxx - lavc 54.7.0 - avcodec.h
16 20
   Add av_codec_is_encoder/decoder().
17 21
 
... ...
@@ -3942,6 +3942,16 @@ int av_get_bits_per_sample(enum CodecID codec_id);
3942 3942
  */
3943 3943
 int av_get_exact_bits_per_sample(enum CodecID codec_id);
3944 3944
 
3945
+/**
3946
+ * Return audio frame duration.
3947
+ *
3948
+ * @param avctx        codec context
3949
+ * @param frame_bytes  size of the frame, or 0 if unknown
3950
+ * @return             frame duration, in samples, if known. 0 if not able to
3951
+ *                     determine.
3952
+ */
3953
+int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes);
3954
+
3945 3955
 /* frame parsing */
3946 3956
 typedef struct AVCodecParserContext {
3947 3957
     void *priv_data;
... ...
@@ -1742,6 +1742,148 @@ int av_get_bits_per_sample(enum CodecID codec_id)
1742 1742
     }
1743 1743
 }
1744 1744
 
1745
+int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
1746
+{
1747
+    int id, sr, ch, ba, tag, bps;
1748
+
1749
+    id  = avctx->codec_id;
1750
+    sr  = avctx->sample_rate;
1751
+    ch  = avctx->channels;
1752
+    ba  = avctx->block_align;
1753
+    tag = avctx->codec_tag;
1754
+    bps = av_get_exact_bits_per_sample(avctx->codec_id);
1755
+
1756
+    /* codecs with an exact constant bits per sample */
1757
+    if (bps > 0 && ch > 0 && frame_bytes > 0)
1758
+        return (frame_bytes * 8) / (bps * ch);
1759
+    bps = avctx->bits_per_coded_sample;
1760
+
1761
+    /* codecs with a fixed packet duration */
1762
+    switch (id) {
1763
+    case CODEC_ID_ADPCM_ADX:    return   32;
1764
+    case CODEC_ID_ADPCM_IMA_QT: return   64;
1765
+    case CODEC_ID_ADPCM_EA_XAS: return  128;
1766
+    case CODEC_ID_AMR_NB:
1767
+    case CODEC_ID_GSM:
1768
+    case CODEC_ID_QCELP:
1769
+    case CODEC_ID_RA_144:
1770
+    case CODEC_ID_RA_288:       return  160;
1771
+    case CODEC_ID_IMC:          return  256;
1772
+    case CODEC_ID_AMR_WB:
1773
+    case CODEC_ID_GSM_MS:       return  320;
1774
+    case CODEC_ID_MP1:          return  384;
1775
+    case CODEC_ID_ATRAC1:       return  512;
1776
+    case CODEC_ID_ATRAC3:       return 1024;
1777
+    case CODEC_ID_MP2:
1778
+    case CODEC_ID_MUSEPACK7:    return 1152;
1779
+    case CODEC_ID_AC3:          return 1536;
1780
+    }
1781
+
1782
+    if (sr > 0) {
1783
+        /* calc from sample rate */
1784
+        if (id == CODEC_ID_TTA)
1785
+            return 256 * sr / 245;
1786
+
1787
+        if (ch > 0) {
1788
+            /* calc from sample rate and channels */
1789
+            if (id == CODEC_ID_BINKAUDIO_DCT)
1790
+                return (480 << (sr / 22050)) / ch;
1791
+        }
1792
+    }
1793
+
1794
+    if (ba > 0) {
1795
+        /* calc from block_align */
1796
+        if (id == CODEC_ID_SIPR) {
1797
+            switch (ba) {
1798
+            case 20: return 160;
1799
+            case 19: return 144;
1800
+            case 29: return 288;
1801
+            case 37: return 480;
1802
+            }
1803
+        }
1804
+    }
1805
+
1806
+    if (frame_bytes > 0) {
1807
+        /* calc from frame_bytes only */
1808
+        if (id == CODEC_ID_TRUESPEECH)
1809
+            return 240 * (frame_bytes / 32);
1810
+        if (id == CODEC_ID_NELLYMOSER)
1811
+            return 256 * (frame_bytes / 64);
1812
+
1813
+        if (bps > 0) {
1814
+            /* calc from frame_bytes and bits_per_coded_sample */
1815
+            if (id == CODEC_ID_ADPCM_G726)
1816
+                return frame_bytes * 8 / bps;
1817
+        }
1818
+
1819
+        if (ch > 0) {
1820
+            /* calc from frame_bytes and channels */
1821
+            switch (id) {
1822
+            case CODEC_ID_ADPCM_4XM:
1823
+            case CODEC_ID_ADPCM_IMA_ISS:
1824
+                return (frame_bytes - 4 * ch) * 2 / ch;
1825
+            case CODEC_ID_ADPCM_IMA_SMJPEG:
1826
+                return (frame_bytes - 4) * 2 / ch;
1827
+            case CODEC_ID_ADPCM_IMA_AMV:
1828
+                return (frame_bytes - 8) * 2 / ch;
1829
+            case CODEC_ID_ADPCM_XA:
1830
+                return (frame_bytes / 128) * 224 / ch;
1831
+            case CODEC_ID_INTERPLAY_DPCM:
1832
+                return (frame_bytes - 6 - ch) / ch;
1833
+            case CODEC_ID_ROQ_DPCM:
1834
+                return (frame_bytes - 8) / ch;
1835
+            case CODEC_ID_XAN_DPCM:
1836
+                return (frame_bytes - 2 * ch) / ch;
1837
+            case CODEC_ID_MACE3:
1838
+                return 3 * frame_bytes / ch;
1839
+            case CODEC_ID_MACE6:
1840
+                return 6 * frame_bytes / ch;
1841
+            case CODEC_ID_PCM_LXF:
1842
+                return 2 * (frame_bytes / (5 * ch));
1843
+            }
1844
+
1845
+            if (tag) {
1846
+                /* calc from frame_bytes, channels, and codec_tag */
1847
+                if (id == CODEC_ID_SOL_DPCM) {
1848
+                    if (tag == 3)
1849
+                        return frame_bytes / ch;
1850
+                    else
1851
+                        return frame_bytes * 2 / ch;
1852
+                }
1853
+            }
1854
+
1855
+            if (ba > 0) {
1856
+                /* calc from frame_bytes, channels, and block_align */
1857
+                int blocks = frame_bytes / ba;
1858
+                switch (avctx->codec_id) {
1859
+                case CODEC_ID_ADPCM_IMA_WAV:
1860
+                    return blocks * (1 + (ba - 4 * ch) / (4 * ch) * 8);
1861
+                case CODEC_ID_ADPCM_IMA_DK3:
1862
+                    return blocks * (((ba - 16) * 8 / 3) / ch);
1863
+                case CODEC_ID_ADPCM_IMA_DK4:
1864
+                    return blocks * (1 + (ba - 4 * ch) * 2 / ch);
1865
+                case CODEC_ID_ADPCM_MS:
1866
+                    return blocks * (2 + (ba - 7 * ch) * 2 / ch);
1867
+                }
1868
+            }
1869
+
1870
+            if (bps > 0) {
1871
+                /* calc from frame_bytes, channels, and bits_per_coded_sample */
1872
+                switch (avctx->codec_id) {
1873
+                case CODEC_ID_PCM_DVD:
1874
+                    return 2 * (frame_bytes / ((bps * 2 / 8) * ch));
1875
+                case CODEC_ID_PCM_BLURAY:
1876
+                    return frame_bytes / ((FFALIGN(ch, 2) * bps) / 8);
1877
+                case CODEC_ID_S302M:
1878
+                    return 2 * (frame_bytes / ((bps + 4) / 4)) / ch;
1879
+                }
1880
+            }
1881
+        }
1882
+    }
1883
+
1884
+    return 0;
1885
+}
1886
+
1745 1887
 #if !HAVE_THREADS
1746 1888
 int ff_thread_init(AVCodecContext *s){
1747 1889
     return -1;
... ...
@@ -21,7 +21,7 @@
21 21
 #define AVCODEC_VERSION_H
22 22
 
23 23
 #define LIBAVCODEC_VERSION_MAJOR 54
24
-#define LIBAVCODEC_VERSION_MINOR  7
24
+#define LIBAVCODEC_VERSION_MINOR  8
25 25
 #define LIBAVCODEC_VERSION_MICRO  0
26 26
 
27 27
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \