* commit '5a7e35dd2351c30bab45177b9482cb8833a0ca78': Add replaygain side data type and code for parsing replaygain tags. Conflicts: libavcodec/avcodec.h libavcodec/version.h libavutil/version.h
Unified · Split
| @@ -15,6 +15,13 @@ libavutil: 2012-10-22 · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | API changes, most recent first: |
| 17 | 17 | |
| 18 | +2014-02-xx - xxxxxxx - lavu 53.07.0 - frame.h, replaygain.h | |
| 19 | + Add AV_FRAME_DATA_REPLAYGAIN for exporting replaygain tags. | |
| 20 | + Add a new header replaygain.h with the AVReplayGain struct. | |
| 21 | + | |
| 22 | +2014-02-xx - xxxxxxx - lavc 55.36.0 - avcodec.h | |
| 23 | + Add AV_PKT_DATA_REPLAYGAIN for exporting replaygain tags. | |
| 24 | + | |
| 18 | 25 | 2014-02-xx - xxxxxxx - lavf 55.13.0 - avformat.h |
| 19 | 26 | Add AVStream.side_data and AVStream.nb_side_data for exporting stream-global |
| 20 | 27 | side data (e.g. replaygain tags, video rotation) |
| @@ -1002,6 +1002,12 @@ enum AVPacketSideDataType { · 1001 unmodified lines | ||
| 1002 | 1002 | */ |
| 1003 | 1003 | AV_PKT_DATA_H263_MB_INFO, |
| 1004 | 1004 | |
| 1005 | + /** | |
| 1006 | + * This side data should be associated with an audio stream and contains | |
| 1007 | + * ReplayGain information in form of the AVReplayGain struct. | |
| 1008 | + */ | |
| 1009 | + AV_PKT_DATA_REPLAYGAIN, | |
| 1010 | + | |
| 1005 | 1011 | /** |
| 1006 | 1012 | * Recommmends skipping the specified number of samples |
| 1007 | 1013 | * @code |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "libavutil/version.h" |
| 30 | 30 | |
| 31 | 31 | #define LIBAVCODEC_VERSION_MAJOR 55 |
| 32 | −#define LIBAVCODEC_VERSION_MINOR 53 | |
| 32 | +#define LIBAVCODEC_VERSION_MINOR 54 | |
| 33 | 33 | #define LIBAVCODEC_VERSION_MICRO 100 |
| 34 | 34 | |
| 35 | 35 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |
| @@ -0,0 +1,154 @@ | ||
| 1 | +/* | |
| 2 | + * This file is part of FFmpeg. | |
| 3 | + * | |
| 4 | + * FFmpeg is free software; you can redistribute it and/or | |
| 5 | + * modify it under the terms of the GNU Lesser General Public | |
| 6 | + * License as published by the Free Software Foundation; either | |
| 7 | + * version 2.1 of the License, or (at your option) any later version. | |
| 8 | + * | |
| 9 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 | + * Lesser General Public License for more details. | |
| 13 | + * | |
| 14 | + * You should have received a copy of the GNU Lesser General Public | |
| 15 | + * License along with FFmpeg; if not, write to the Free Software | |
| 16 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 17 | + */ | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * @file | |
| 21 | + * replaygain tags parsing | |
| 22 | + */ | |
| 23 | + | |
| 24 | +#include <stdint.h> | |
| 25 | +#include <stdlib.h> | |
| 26 | +#include <string.h> | |
| 27 | + | |
| 28 | +#include "libavutil/avstring.h" | |
| 29 | +#include "libavutil/dict.h" | |
| 30 | +#include "libavutil/intreadwrite.h" | |
| 31 | +#include "libavutil/mathematics.h" | |
| 32 | +#include "libavutil/mem.h" | |
| 33 | +#include "libavutil/replaygain.h" | |
| 34 | + | |
| 35 | +#include "avformat.h" | |
| 36 | +#include "replaygain.h" | |
| 37 | + | |
| 38 | +static int32_t parse_gain(const char *gain) | |
| 39 | +{ | |
| 40 | + char *fraction; | |
| 41 | + int scale = 10000; | |
| 42 | + int32_t mb = 0; | |
| 43 | + int db; | |
| 44 | + | |
| 45 | + if (!gain) | |
| 46 | + return INT32_MIN; | |
| 47 | + | |
| 48 | + gain += strspn(gain, " \t"); | |
| 49 | + | |
| 50 | + db = strtol(gain, &fraction, 0); | |
| 51 | + if (*fraction++ == '.') { | |
| 52 | + while (av_isdigit(*fraction) && scale) { | |
| 53 | + mb += scale * (*fraction - '0'); | |
| 54 | + scale /= 10; | |
| 55 | + fraction++; | |
| 56 | + } | |
| 57 | + } | |
| 58 | + | |
| 59 | + if (abs(db) > (INT32_MAX - mb) / 100000) | |
| 60 | + return INT32_MIN; | |
| 61 | + | |
| 62 | + return db * 100000 + FFSIGN(db) * mb; | |
| 63 | +} | |
| 64 | + | |
| 65 | +static uint32_t parse_peak(const uint8_t *peak) | |
| 66 | +{ | |
| 67 | + int64_t val = 0; | |
| 68 | + int64_t scale = 1; | |
| 69 | + | |
| 70 | + if (!peak) | |
| 71 | + return 0; | |
| 72 | + | |
| 73 | + peak += strspn(peak, " \t"); | |
| 74 | + | |
| 75 | + if (peak[0] == '1' && peak[1] == '.') | |
| 76 | + return UINT32_MAX; | |
| 77 | + else if (!(peak[0] == '0' && peak[1] == '.')) | |
| 78 | + return 0; | |
| 79 | + | |
| 80 | + peak += 2; | |
| 81 | + | |
| 82 | + while (av_isdigit(*peak)) { | |
| 83 | + int digit = *peak - '0'; | |
| 84 | + | |
| 85 | + if (scale > INT64_MAX / 10) | |
| 86 | + break; | |
| 87 | + | |
| 88 | + val = 10 * val + digit; | |
| 89 | + scale *= 10; | |
| 90 | + | |
| 91 | + peak++; | |
| 92 | + } | |
| 93 | + | |
| 94 | + return av_rescale(val, UINT32_MAX, scale); | |
| 95 | +} | |
| 96 | + | |
| 97 | +static int replaygain_export(AVStream *st, | |
| 98 | + const uint8_t *track_gain, const uint8_t *track_peak, | |
| 99 | + const uint8_t *album_gain, const uint8_t *album_peak) | |
| 100 | +{ | |
| 101 | + AVPacketSideData *sd, *tmp; | |
| 102 | + AVReplayGain *replaygain; | |
| 103 | + uint8_t *data; | |
| 104 | + int32_t tg, ag; | |
| 105 | + uint32_t tp, ap; | |
| 106 | + | |
| 107 | + tg = parse_gain(track_gain); | |
| 108 | + ag = parse_gain(album_gain); | |
| 109 | + tp = parse_peak(track_peak); | |
| 110 | + ap = parse_peak(album_peak); | |
| 111 | + | |
| 112 | + if (tg == INT32_MIN && ag == INT32_MIN) | |
| 113 | + return 0; | |
| 114 | + | |
| 115 | + replaygain = av_mallocz(sizeof(*replaygain)); | |
| 116 | + if (!replaygain) | |
| 117 | + return AVERROR(ENOMEM); | |
| 118 | + | |
| 119 | + tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp)); | |
| 120 | + if (!tmp) { | |
| 121 | + av_freep(&replaygain); | |
| 122 | + return AVERROR(ENOMEM); | |
| 123 | + } | |
| 124 | + st->side_data = tmp; | |
| 125 | + st->nb_side_data++; | |
| 126 | + | |
| 127 | + sd = &st->side_data[st->nb_side_data - 1]; | |
| 128 | + sd->type = AV_PKT_DATA_REPLAYGAIN; | |
| 129 | + sd->data = (uint8_t*)replaygain; | |
| 130 | + sd->size = sizeof(*replaygain); | |
| 131 | + | |
| 132 | + replaygain->track_gain = tg; | |
| 133 | + replaygain->track_peak = tp; | |
| 134 | + replaygain->album_gain = ag; | |
| 135 | + replaygain->album_peak = ap; | |
| 136 | + | |
| 137 | + return 0; | |
| 138 | +} | |
| 139 | + | |
| 140 | +int ff_replaygain_export(AVStream *st, AVDictionary *metadata) | |
| 141 | +{ | |
| 142 | + const AVDictionaryEntry *tg, *tp, *ag, *ap; | |
| 143 | + | |
| 144 | + tg = av_dict_get(metadata, "REPLAYGAIN_TRACK_GAIN", NULL, 0); | |
| 145 | + tp = av_dict_get(metadata, "REPLAYGAIN_TRACK_PEAK", NULL, 0); | |
| 146 | + ag = av_dict_get(metadata, "REPLAYGAIN_ALBUM_GAIN", NULL, 0); | |
| 147 | + ap = av_dict_get(metadata, "REPLAYGAIN_ALBUM_PEAK", NULL, 0); | |
| 148 | + | |
| 149 | + return replaygain_export(st, | |
| 150 | + tg ? tg->value : NULL, | |
| 151 | + tp ? tp->value : NULL, | |
| 152 | + ag ? ag->value : NULL, | |
| 153 | + ap ? ap->value : NULL); | |
| 154 | +} | |
| @@ -0,0 +1,31 @@ | ||
| 1 | +/* | |
| 2 | + * This file is part of FFmpeg. | |
| 3 | + * | |
| 4 | + * FFmpeg is free software; you can redistribute it and/or | |
| 5 | + * modify it under the terms of the GNU Lesser General Public | |
| 6 | + * License as published by the Free Software Foundation; either | |
| 7 | + * version 2.1 of the License, or (at your option) any later version. | |
| 8 | + * | |
| 9 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 | + * Lesser General Public License for more details. | |
| 13 | + * | |
| 14 | + * You should have received a copy of the GNU Lesser General Public | |
| 15 | + * License along with FFmpeg; if not, write to the Free Software | |
| 16 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#ifndef AVFORMAT_REPLAYGAIN_H | |
| 20 | +#define AVFORMAT_REPLAYGAIN_H | |
| 21 | + | |
| 22 | +#include "libavutil/dict.h" | |
| 23 | + | |
| 24 | +#include "avformat.h" | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * Parse replaygain tags and export them as per-stream side data. | |
| 28 | + */ | |
| 29 | +int ff_replaygain_export(AVStream *st, AVDictionary *metadata); | |
| 30 | + | |
| 31 | +#endif /* AVFORMAT_REPLAYGAIN_H */ | |
| @@ -44,6 +44,7 @@ HEADERS = adler32.h \ · 43 unmodified lines | ||
| 44 | 44 | pixdesc.h \ |
| 45 | 45 | pixfmt.h \ |
| 46 | 46 | random_seed.h \ |
| 47 | + replaygain.h \ | |
| 47 | 48 | rational.h \ |
| 48 | 49 | ripemd.h \ |
| 49 | 50 | samplefmt.h \ |
| @@ -92,6 +92,10 @@ enum AVFrameSideDataType { · 91 unmodified lines | ||
| 92 | 92 | * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. |
| 93 | 93 | */ |
| 94 | 94 | AV_FRAME_DATA_DOWNMIX_INFO, |
| 95 | + /** | |
| 96 | + * ReplayGain information in the form of the AVReplayGain struct. | |
| 97 | + */ | |
| 98 | + AV_FRAME_DATA_REPLAYGAIN, | |
| 95 | 99 | }; |
| 96 | 100 | |
| 97 | 101 | typedef struct AVFrameSideData { |
| @@ -0,0 +1,51 @@ | ||
| 1 | +/* | |
| 2 | + * | |
| 3 | + * This file is part of FFmpeg. | |
| 4 | + * | |
| 5 | + * FFmpeg is free software; you can redistribute it and/or | |
| 6 | + * modify it under the terms of the GNU Lesser General Public | |
| 7 | + * License as published by the Free Software Foundation; either | |
| 8 | + * version 2.1 of the License, or (at your option) any later version. | |
| 9 | + * | |
| 10 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | + * Lesser General Public License for more details. | |
| 14 | + * | |
| 15 | + * You should have received a copy of the GNU Lesser General Public | |
| 16 | + * License along with FFmpeg; if not, write to the Free Software | |
| 17 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 18 | + */ | |
| 19 | + | |
| 20 | +#ifndef AVUTIL_REPLAYGAIN_H | |
| 21 | +#define AVUTIL_REPLAYGAIN_H | |
| 22 | + | |
| 23 | +#include <stdint.h> | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * ReplayGain information (see | |
| 27 | + * http://wiki.hydrogenaudio.org/index.php?title=ReplayGain_1.0_specification). | |
| 28 | + * The size of this struct is a part of the public ABI. | |
| 29 | + */ | |
| 30 | +typedef struct AVReplayGain { | |
| 31 | + /** | |
| 32 | + * Track replay gain in microbels (divide by 100000 to get the value in dB). | |
| 33 | + * Should be set to INT32_MIN when unknown. | |
| 34 | + */ | |
| 35 | + int32_t track_gain; | |
| 36 | + /** | |
| 37 | + * Peak track amplitude, with UINT32_MAX representing full scale. 0 when | |
| 38 | + * unknown. | |
| 39 | + */ | |
| 40 | + uint32_t track_peak; | |
| 41 | + /** | |
| 42 | + * Same as track_gain, but for the whole album. | |
| 43 | + */ | |
| 44 | + int32_t album_gain; | |
| 45 | + /** | |
| 46 | + * Same as track_peak, but for the whole album, | |
| 47 | + */ | |
| 48 | + uint32_t album_peak; | |
| 49 | +} AVReplayGain; | |
| 50 | + | |
| 51 | +#endif /* AVUTIL_REPLAYGAIN_H */ | |
| @@ -56,7 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | */ |
| 57 | 57 | |
| 58 | 58 | #define LIBAVUTIL_VERSION_MAJOR 52 |
| 59 | −#define LIBAVUTIL_VERSION_MINOR 67 | |
| 59 | +#define LIBAVUTIL_VERSION_MINOR 68 | |
| 60 | 60 | #define LIBAVUTIL_VERSION_MICRO 100 |
| 61 | 61 | |
| 62 | 62 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |