Statistics
| Branch: | Revision:

ffmpeg / libavformat / oggparseogm.c @ a351110e

History | View | Annotate | Download (5.69 KB)

1
/**
2
    Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
3

4
    Permission is hereby granted, free of charge, to any person
5
    obtaining a copy of this software and associated documentation
6
    files (the "Software"), to deal in the Software without
7
    restriction, including without limitation the rights to use, copy,
8
    modify, merge, publish, distribute, sublicense, and/or sell copies
9
    of the Software, and to permit persons to whom the Software is
10
    furnished to do so, subject to the following conditions:
11

12
    The above copyright notice and this permission notice shall be
13
    included in all copies or substantial portions of the Software.
14

15
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
    DEALINGS IN THE SOFTWARE.
23
**/
24

    
25
#include <stdlib.h>
26
#include "libavutil/intreadwrite.h"
27
#include "libavcodec/get_bits.h"
28
#include "libavcodec/bytestream.h"
29
#include "avformat.h"
30
#include "oggdec.h"
31
#include "riff.h"
32

    
33
static int
34
ogm_header(AVFormatContext *s, int idx)
35
{
36
    struct ogg *ogg = s->priv_data;
37
    struct ogg_stream *os = ogg->streams + idx;
38
    AVStream *st = s->streams[idx];
39
    const uint8_t *p = os->buf + os->pstart;
40
    uint64_t time_unit;
41
    uint64_t spu;
42
    uint32_t default_len;
43

    
44
    if(!(*p & 1))
45
        return 0;
46

    
47
    if(*p == 1) {
48
        p++;
49

    
50
        if(*p == 'v'){
51
            int tag;
52
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
53
            p += 8;
54
            tag = bytestream_get_le32(&p);
55
            st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag);
56
            st->codec->codec_tag = tag;
57
        } else if (*p == 't') {
58
            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
59
            st->codec->codec_id = CODEC_ID_TEXT;
60
            p += 12;
61
        } else {
62
            uint8_t acid[5];
63
            int cid;
64
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
65
            p += 8;
66
            bytestream_get_buffer(&p, acid, 4);
67
            acid[4] = 0;
68
            cid = strtol(acid, NULL, 16);
69
            st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid);
70
            st->need_parsing = AVSTREAM_PARSE_FULL;
71
        }
72

    
73
        p += 4;                     /* useless size field */
74

    
75
        time_unit   = bytestream_get_le64(&p);
76
        spu         = bytestream_get_le64(&p);
77
        default_len = bytestream_get_le32(&p);
78

    
79
        p += 8;                     /* buffersize + bits_per_sample */
80

    
81
        if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
82
            st->codec->width = bytestream_get_le32(&p);
83
            st->codec->height = bytestream_get_le32(&p);
84
            st->codec->time_base.den = spu * 10000000;
85
            st->codec->time_base.num = time_unit;
86
            av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
87
        } else {
88
            st->codec->channels = bytestream_get_le16(&p);
89
            p += 2;                 /* block_align */
90
            st->codec->bit_rate = bytestream_get_le32(&p) * 8;
91
            st->codec->sample_rate = spu * 10000000 / time_unit;
92
            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
93
        }
94
    } else if (*p == 3) {
95
        if (os->psize > 8)
96
            ff_vorbis_comment(s, &st->metadata, p+7, os->psize-8);
97
    }
98

    
99
    return 1;
100
}
101

    
102
static int
103
ogm_dshow_header(AVFormatContext *s, int idx)
104
{
105
    struct ogg *ogg = s->priv_data;
106
    struct ogg_stream *os = ogg->streams + idx;
107
    AVStream *st = s->streams[idx];
108
    uint8_t *p = os->buf + os->pstart;
109
    uint32_t t;
110

    
111
    if(!(*p & 1))
112
        return 0;
113
    if(*p != 1)
114
        return 1;
115

    
116
    t = AV_RL32(p + 96);
117

    
118
    if(t == 0x05589f80){
119
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
120
        st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(p + 68));
121
        st->codec->time_base.den = 10000000;
122
        st->codec->time_base.num = AV_RL64(p + 164);
123
        st->codec->width = AV_RL32(p + 176);
124
        st->codec->height = AV_RL32(p + 180);
125
    } else if(t == 0x05589f81){
126
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
127
        st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, AV_RL16(p + 124));
128
        st->codec->channels = AV_RL16(p + 126);
129
        st->codec->sample_rate = AV_RL32(p + 128);
130
        st->codec->bit_rate = AV_RL32(p + 132) * 8;
131
    }
132

    
133
    return 1;
134
}
135

    
136
static int
137
ogm_packet(AVFormatContext *s, int idx)
138
{
139
    struct ogg *ogg = s->priv_data;
140
    struct ogg_stream *os = ogg->streams + idx;
141
    uint8_t *p = os->buf + os->pstart;
142
    int lb;
143

    
144
    if(*p & 8)
145
        os->pflags |= AV_PKT_FLAG_KEY;
146

    
147
    lb = ((*p & 2) << 1) | ((*p >> 6) & 3);
148
    os->pstart += lb + 1;
149
    os->psize -= lb + 1;
150

    
151
    while (lb--)
152
        os->pduration += p[lb+1] << (lb*8);
153

    
154
    return 0;
155
}
156

    
157
const struct ogg_codec ff_ogm_video_codec = {
158
    .magic = "\001video",
159
    .magicsize = 6,
160
    .header = ogm_header,
161
    .packet = ogm_packet,
162
    .granule_is_start = 1,
163
};
164

    
165
const struct ogg_codec ff_ogm_audio_codec = {
166
    .magic = "\001audio",
167
    .magicsize = 6,
168
    .header = ogm_header,
169
    .packet = ogm_packet,
170
    .granule_is_start = 1,
171
};
172

    
173
const struct ogg_codec ff_ogm_text_codec = {
174
    .magic = "\001text",
175
    .magicsize = 5,
176
    .header = ogm_header,
177
    .packet = ogm_packet,
178
    .granule_is_start = 1,
179
};
180

    
181
const struct ogg_codec ff_ogm_old_codec = {
182
    .magic = "\001Direct Show Samples embedded in Ogg",
183
    .magicsize = 35,
184
    .header = ogm_dshow_header,
185
    .packet = ogm_packet,
186
    .granule_is_start = 1,
187
};