annotate oggparsespeex.c @ 6048:e507a21a9566 libavformat

matroskaenc: Write codec time base as default duration for video tracks. This isn't exactly semantically equivalent, but the field has already been long abused to mean this, and writing it helps in determining a decent cfr time base when transcoding from a mkv where the video codec stores none (VP8).
author conrad
date Mon, 24 May 2010 08:58:19 +0000
parents 536e5527c1e0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
1 /*
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
2 Copyright (C) 2008 Reimar Döffinger
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
3
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
4 Permission is hereby granted, free of charge, to any person
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
5 obtaining a copy of this software and associated documentation
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
6 files (the "Software"), to deal in the Software without
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
7 restriction, including without limitation the rights to use, copy,
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
8 modify, merge, publish, distribute, sublicense, and/or sell copies
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
9 of the Software, and to permit persons to whom the Software is
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
10 furnished to do so, subject to the following conditions:
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
11
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
12 The above copyright notice and this permission notice shall be
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
13 included in all copies or substantial portions of the Software.
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
14
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
22 DEALINGS IN THE SOFTWARE.
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
23 **/
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
24
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
25 #include <stdlib.h>
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3023
diff changeset
26 #include "libavutil/bswap.h"
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3023
diff changeset
27 #include "libavutil/avstring.h"
4872
304a0ea063f0 Rename bitstream.h to get_bits.h.
stefano
parents: 4766
diff changeset
28 #include "libavcodec/get_bits.h"
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 3023
diff changeset
29 #include "libavcodec/bytestream.h"
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
30 #include "avformat.h"
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
31 #include "oggdec.h"
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
32
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
33 struct speex_params {
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
34 int final_packet_duration;
5814
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
35 int seq;
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
36 };
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
37
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
38 static int speex_header(AVFormatContext *s, int idx) {
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3770
diff changeset
39 struct ogg *ogg = s->priv_data;
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3770
diff changeset
40 struct ogg_stream *os = ogg->streams + idx;
5814
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
41 struct speex_params *spxp = os->private;
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
42 AVStream *st = s->streams[idx];
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
43 uint8_t *p = os->buf + os->pstart;
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
44
5814
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
45 if (!spxp) {
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
46 spxp = av_mallocz(sizeof(*spxp));
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
47 os->private = spxp;
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
48 }
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
49
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
50 if (spxp->seq > 1)
4765
6ab95f681099 Fix Speex header parsing in ogg demuxer
conrad
parents: 4016
diff changeset
51 return 0;
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
52
5814
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
53 if (spxp->seq == 0) {
5152
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
54 int frames_per_packet;
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 5824
diff changeset
55 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
4766
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
56 st->codec->codec_id = CODEC_ID_SPEEX;
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
57
4766
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
58 st->codec->sample_rate = AV_RL32(p + 36);
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
59 st->codec->channels = AV_RL32(p + 48);
5152
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
60
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
61 /* We treat the whole Speex packet as a single frame everywhere Speex
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
62 is handled in FFmpeg. This avoids the complexities of splitting
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
63 and joining individual Speex frames, which are not always
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
64 byte-aligned. */
4948
09e81ac02d25 Set speex frame_size in ogg demuxer
conrad
parents: 4872
diff changeset
65 st->codec->frame_size = AV_RL32(p + 56);
5152
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
66 frames_per_packet = AV_RL32(p + 64);
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
67 if (frames_per_packet)
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
68 st->codec->frame_size *= frames_per_packet;
ab5ed34ed707 Modify the Ogg/Speex demuxer and the libspeex decoder so that they always treat
jbr
parents: 5005
diff changeset
69
4766
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
70 st->codec->extradata_size = os->psize;
5005
53092c7684a2 Ensure that the extradata buffer is padded appripriately in the ogg demuxer.
conrad
parents: 4948
diff changeset
71 st->codec->extradata = av_malloc(st->codec->extradata_size
53092c7684a2 Ensure that the extradata buffer is padded appripriately in the ogg demuxer.
conrad
parents: 4948
diff changeset
72 + FF_INPUT_BUFFER_PADDING_SIZE);
4766
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
73 memcpy(st->codec->extradata, p, st->codec->extradata_size);
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
74
4766
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
75 st->time_base.num = 1;
6567b8869917 Reindent
conrad
parents: 4765
diff changeset
76 st->time_base.den = st->codec->sample_rate;
4765
6ab95f681099 Fix Speex header parsing in ogg demuxer
conrad
parents: 4016
diff changeset
77 } else
5824
b9f21d75c81a oggdec: Metadata is per-stream; don't merge multiple streams' together
conrad
parents: 5823
diff changeset
78 ff_vorbis_comment(s, &st->metadata, p, os->psize);
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
79
5814
e993cab1faf3 oggdec: Don't use ogg_stream's seq for vorbis or speex headers
conrad
parents: 5434
diff changeset
80 spxp->seq++;
4765
6ab95f681099 Fix Speex header parsing in ogg demuxer
conrad
parents: 4016
diff changeset
81 return 1;
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
82 }
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
83
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
84 static int ogg_page_packets(struct ogg_stream *os)
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
85 {
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
86 int i;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
87 int packets = 0;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
88 for (i = 0; i < os->nsegs; i++)
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
89 if (os->segments[i] < 255)
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
90 packets++;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
91 return packets;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
92 }
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
93
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
94 static int speex_packet(AVFormatContext *s, int idx)
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
95 {
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
96 struct ogg *ogg = s->priv_data;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
97 struct ogg_stream *os = ogg->streams + idx;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
98 struct speex_params *spxp = os->private;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
99 int packet_size = s->streams[idx]->codec->frame_size;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
100
5434
68c8e7affd44 Fix PTS for OGM codecs.
conrad
parents: 5276
diff changeset
101 if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE &&
68c8e7affd44 Fix PTS for OGM codecs.
conrad
parents: 5276
diff changeset
102 os->granule > 0) {
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
103 /* first packet of final page. we have to calculate the final packet
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
104 duration here because it is the only place we know the next-to-last
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
105 granule position. */
5434
68c8e7affd44 Fix PTS for OGM codecs.
conrad
parents: 5276
diff changeset
106 spxp->final_packet_duration = os->granule - os->lastpts -
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
107 packet_size * (ogg_page_packets(os) - 1);
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
108 }
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
109
5434
68c8e7affd44 Fix PTS for OGM codecs.
conrad
parents: 5276
diff changeset
110 if (!os->lastpts && os->granule > 0)
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
111 /* first packet */
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
112 os->pduration = os->granule - packet_size * (ogg_page_packets(os) - 1);
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
113 else if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs &&
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
114 spxp->final_packet_duration)
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
115 /* final packet */
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
116 os->pduration = spxp->final_packet_duration;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
117 else
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
118 os->pduration = packet_size;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
119
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
120 return 0;
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
121 }
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
122
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3770
diff changeset
123 const struct ogg_codec ff_speex_codec = {
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
124 .magic = "Speex ",
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
125 .magicsize = 8,
5276
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
126 .header = speex_header,
5de92e352cf9 Calculate correct packet durations when demuxing Ogg/Speex. This involves
jbr
parents: 5152
diff changeset
127 .packet = speex_packet
3023
61ea9e6ee162 Add support for speex in ogg
reimar
parents:
diff changeset
128 };