ffmpeg / libavformat / oggparsespeex.c @ a351110e
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 | is handled in FFmpeg. This avoids the complexities of splitting
|
||
63 | 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 | }; |