Revision 6afd0ee3 libavformat/oma.c

View differences:

libavformat/oma.c
27 27
 *
28 28
 * Known file extensions: ".oma", "aa3"
29 29
 * The format of such files consists of three parts:
30
 * - "ea3" header carrying overall info and metadata.
30
 * - "ea3" header carrying overall info and metadata. Except for starting with
31
 *   "ea" instead of "ID", it's an ID3v2 header.
31 32
 * - "EA3" header is a Sony-specific header containing information about
32 33
 *   the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
33 34
 *   codec specific info (packet size, sample rate, channels and so on)
......
46 47
#include "libavutil/intreadwrite.h"
47 48
#include "raw.h"
48 49
#include "riff.h"
50
#include "id3v2.h"
49 51

  
50 52
#define EA3_HEADER_SIZE 96
51 53

  
......
63 65
    { CODEC_ID_MP3,     OMA_CODECID_MP3 },
64 66
};
65 67

  
68
#define ID3v2_EA3_MAGIC "ea3"
69

  
66 70
static int oma_read_header(AVFormatContext *s,
67 71
                           AVFormatParameters *ap)
68 72
{
69 73
    static const uint16_t srate_tab[6] = {320,441,480,882,960,0};
70
    int     ret, ea3_taglen, EA3_pos, framesize, jsflag, samplerate;
74
    int     ret, framesize, jsflag, samplerate;
71 75
    uint32_t codec_params;
72 76
    int16_t eid;
73 77
    uint8_t buf[EA3_HEADER_SIZE];
74 78
    uint8_t *edata;
75 79
    AVStream *st;
76 80

  
77
    ret = get_buffer(s->pb, buf, 10);
78
    if (ret != 10)
79
        return -1;
80

  
81
    if(!memcmp(buf, "ea3", 3)) {
82
        ea3_taglen = ((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f);
83

  
84
        EA3_pos = ea3_taglen + 10;
85
        if (buf[5] & 0x10)
86
            EA3_pos += 10;
87

  
88
        url_fseek(s->pb, EA3_pos, SEEK_SET);
89
        ret = get_buffer(s->pb, buf, EA3_HEADER_SIZE);
90
        if (ret != EA3_HEADER_SIZE)
91
            return -1;
92
    } else {
93
        ret = get_buffer(s->pb, buf + 10, EA3_HEADER_SIZE - 10);
94
        EA3_pos = 0;
95
    }
81
    ff_id3v2_read(s, ID3v2_EA3_MAGIC);
82
    ret = get_buffer(s->pb, buf, EA3_HEADER_SIZE);
96 83

  
97 84
    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
98 85
        av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
......
163 150
    }
164 151

  
165 152
    st->codec->block_align = framesize;
166
    url_fseek(s->pb, EA3_pos + EA3_HEADER_SIZE, SEEK_SET);
167 153

  
168 154
    return 0;
169 155
}
......
182 168

  
183 169
static int oma_read_probe(AVProbeData *p)
184 170
{
185
    if (!memcmp(p->buf, ((const uint8_t[]){'e', 'a', '3', 3, 0}), 5) ||
186
        (!memcmp(p->buf, "EA3", 3) &&
187
         !p->buf[4] && p->buf[5] == EA3_HEADER_SIZE))
171
    const uint8_t *buf;
172
    unsigned tag_len = 0;
173

  
174
    buf = p->buf;
175
    /* version must be 3 and flags byte zero */
176
    if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4])
177
        tag_len = ff_id3v2_tag_len(buf);
178

  
179
    // This check cannot overflow as tag_len has at most 28 bits
180
    if (p->buf_size < tag_len + 5)
181
        return 0;
182

  
183
    buf += tag_len;
184

  
185
    if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
188 186
        return AVPROBE_SCORE_MAX;
189 187
    else
190 188
        return 0;
......
203 201
    .flags= AVFMT_GENERIC_INDEX,
204 202
    .extensions = "oma,aa3",
205 203
    .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0},
204
    .metadata_conv = ff_id3v2_metadata_conv,
206 205
};
207 206

  

Also available in: Unified diff