Statistics
| Branch: | Revision:

ffmpeg / libavformat / oggparsespeex.c @ 2d2b5a14

History | View | Annotate | Download (4.27 KB)

1 cb4ddf77 Reimar Döffinger
/*
2
      Copyright (C) 2008  Reimar Döffinger
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 245976da Diego Biurrun
#include "libavutil/bswap.h"
27
#include "libavutil/avstring.h"
28 9106a698 Stefano Sabatini
#include "libavcodec/get_bits.h"
29 245976da Diego Biurrun
#include "libavcodec/bytestream.h"
30 cb4ddf77 Reimar Döffinger
#include "avformat.h"
31
#include "oggdec.h"
32
33 15299b38 Justin Ruggles
struct speex_params {
34
    int final_packet_duration;
35 8f8320d7 David Conrad
    int seq;
36 15299b38 Justin Ruggles
};
37
38 cb4ddf77 Reimar Döffinger
static int speex_header(AVFormatContext *s, int idx) {
39 77be08ee Måns Rullgård
    struct ogg *ogg = s->priv_data;
40
    struct ogg_stream *os = ogg->streams + idx;
41 8f8320d7 David Conrad
    struct speex_params *spxp = os->private;
42 cb4ddf77 Reimar Döffinger
    AVStream *st = s->streams[idx];
43
    uint8_t *p = os->buf + os->pstart;
44
45 8f8320d7 David Conrad
    if (!spxp) {
46
        spxp = av_mallocz(sizeof(*spxp));
47
        os->private = spxp;
48
    }
49
50
    if (spxp->seq > 1)
51 6e6abd02 David Conrad
        return 0;
52 cb4ddf77 Reimar Döffinger
53 8f8320d7 David Conrad
    if (spxp->seq == 0) {
54 eb5f3c54 Justin Ruggles
        int frames_per_packet;
55 72415b2a Stefano Sabatini
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
56 1a4ab332 David Conrad
        st->codec->codec_id = CODEC_ID_SPEEX;
57 cb4ddf77 Reimar Döffinger
58 1a4ab332 David Conrad
        st->codec->sample_rate = AV_RL32(p + 36);
59
        st->codec->channels = AV_RL32(p + 48);
60 eb5f3c54 Justin Ruggles
61
        /* We treat the whole Speex packet as a single frame everywhere Speex
62 2d2b5a14 Michael Niedermayer
           is handled in FFmpeg.  This avoids the complexities of splitting
63 eb5f3c54 Justin Ruggles
           and joining individual Speex frames, which are not always
64
           byte-aligned. */
65 533c3c84 David Conrad
        st->codec->frame_size = AV_RL32(p + 56);
66 eb5f3c54 Justin Ruggles
        frames_per_packet     = AV_RL32(p + 64);
67
        if (frames_per_packet)
68
            st->codec->frame_size *= frames_per_packet;
69
70 1a4ab332 David Conrad
        st->codec->extradata_size = os->psize;
71 12d7c079 David Conrad
        st->codec->extradata = av_malloc(st->codec->extradata_size
72
                                         + FF_INPUT_BUFFER_PADDING_SIZE);
73 1a4ab332 David Conrad
        memcpy(st->codec->extradata, p, st->codec->extradata_size);
74 cb4ddf77 Reimar Döffinger
75 a351110e Reimar Döffinger
        av_set_pts_info(st, 64, 1, st->codec->sample_rate);
76 6e6abd02 David Conrad
    } else
77 b53cde48 David Conrad
        ff_vorbis_comment(s, &st->metadata, p, os->psize);
78 cb4ddf77 Reimar Döffinger
79 8f8320d7 David Conrad
    spxp->seq++;
80 6e6abd02 David Conrad
    return 1;
81 cb4ddf77 Reimar Döffinger
}
82
83 15299b38 Justin Ruggles
static int ogg_page_packets(struct ogg_stream *os)
84
{
85
    int i;
86
    int packets = 0;
87
    for (i = 0; i < os->nsegs; i++)
88
        if (os->segments[i] < 255)
89
            packets++;
90
    return packets;
91
}
92
93
static int speex_packet(AVFormatContext *s, int idx)
94
{
95
    struct ogg *ogg = s->priv_data;
96
    struct ogg_stream *os = ogg->streams + idx;
97
    struct speex_params *spxp = os->private;
98
    int packet_size = s->streams[idx]->codec->frame_size;
99
100 5e15c7d9 David Conrad
    if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE &&
101
        os->granule > 0) {
102 15299b38 Justin Ruggles
        /* first packet of final page. we have to calculate the final packet
103
           duration here because it is the only place we know the next-to-last
104
           granule position. */
105 5e15c7d9 David Conrad
        spxp->final_packet_duration = os->granule - os->lastpts -
106 15299b38 Justin Ruggles
                                      packet_size * (ogg_page_packets(os) - 1);
107
    }
108
109 5e15c7d9 David Conrad
    if (!os->lastpts && os->granule > 0)
110 15299b38 Justin Ruggles
        /* first packet */
111
        os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
112
    else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
113
             spxp->final_packet_duration)
114
        /* final packet */
115
        os->pduration = spxp->final_packet_duration;
116
    else
117
        os->pduration = packet_size;
118
119
    return 0;
120
}
121
122 77be08ee Måns Rullgård
const struct ogg_codec ff_speex_codec = {
123 cb4ddf77 Reimar Döffinger
    .magic = "Speex   ",
124
    .magicsize = 8,
125 15299b38 Justin Ruggles
    .header = speex_header,
126
    .packet = speex_packet
127 cb4ddf77 Reimar Döffinger
};