Mercurial > libavformat.hg
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 |
rev | line source |
---|---|
3023 | 1 /* |
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> | |
3286 | 26 #include "libavutil/bswap.h" |
27 #include "libavutil/avstring.h" | |
4872 | 28 #include "libavcodec/get_bits.h" |
3286 | 29 #include "libavcodec/bytestream.h" |
3023 | 30 #include "avformat.h" |
31 #include "oggdec.h" | |
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 | 38 static int speex_header(AVFormatContext *s, int idx) { |
4016 | 39 struct ogg *ogg = s->priv_data; |
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 | 42 AVStream *st = s->streams[idx]; |
43 uint8_t *p = os->buf + os->pstart; | |
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 | 51 return 0; |
3023 | 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 | 56 st->codec->codec_id = CODEC_ID_SPEEX; |
3023 | 57 |
4766 | 58 st->codec->sample_rate = AV_RL32(p + 36); |
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 | 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 | 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 | 73 memcpy(st->codec->extradata, p, st->codec->extradata_size); |
3023 | 74 |
4766 | 75 st->time_base.num = 1; |
76 st->time_base.den = st->codec->sample_rate; | |
4765 | 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 | 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 | 81 return 1; |
3023 | 82 } |
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 | 101 if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE && |
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 | 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 | 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 | 123 const struct ogg_codec ff_speex_codec = { |
3023 | 124 .magic = "Speex ", |
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 | 128 }; |