FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
oggparseogm.c
Go to the documentation of this file.
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/avassert.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavcodec/get_bits.h"
29 #include "libavcodec/bytestream.h"
30 #include "avformat.h"
31 #include "internal.h"
32 #include "oggdec.h"
33 #include "riff.h"
34 
35 static int
37 {
38  struct ogg *ogg = s->priv_data;
39  struct ogg_stream *os = ogg->streams + idx;
40  AVStream *st = s->streams[idx];
42  uint64_t time_unit;
43  uint64_t spu;
44  uint32_t size;
45 
46  bytestream2_init(&p, os->buf + os->pstart, os->psize);
47  if (!(bytestream2_peek_byte(&p) & 1))
48  return 0;
49 
50  if (bytestream2_peek_byte(&p) == 1) {
51  bytestream2_skip(&p, 1);
52 
53  if (bytestream2_peek_byte(&p) == 'v'){
54  int tag;
56  bytestream2_skip(&p, 8);
57  tag = bytestream2_get_le32(&p);
59  st->codec->codec_tag = tag;
60  } else if (bytestream2_peek_byte(&p) == 't') {
63  bytestream2_skip(&p, 12);
64  } else {
65  uint8_t acid[5] = { 0 };
66  int cid;
68  bytestream2_skip(&p, 8);
69  bytestream2_get_buffer(&p, acid, 4);
70  acid[4] = 0;
71  cid = strtol(acid, NULL, 16);
73  // our parser completely breaks AAC in Ogg
74  if (st->codec->codec_id != AV_CODEC_ID_AAC)
76  }
77 
78  size = bytestream2_get_le32(&p);
79  size = FFMIN(size, os->psize);
80  time_unit = bytestream2_get_le64(&p);
81  spu = bytestream2_get_le64(&p);
82  if (!time_unit || !spu) {
83  av_log(s, AV_LOG_ERROR, "Invalid timing values.\n");
84  return AVERROR_INVALIDDATA;
85  }
86 
87  bytestream2_skip(&p, 4); /* default_len */
88  bytestream2_skip(&p, 8); /* buffersize + bits_per_sample */
89 
91  st->codec->width = bytestream2_get_le32(&p);
92  st->codec->height = bytestream2_get_le32(&p);
93  avpriv_set_pts_info(st, 64, time_unit, spu * 10000000);
94  } else {
95  st->codec->channels = bytestream2_get_le16(&p);
96  bytestream2_skip(&p, 2); /* block_align */
97  st->codec->bit_rate = bytestream2_get_le32(&p) * 8;
98  st->codec->sample_rate = spu * 10000000 / time_unit;
99  avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
100  if (size >= 56 && st->codec->codec_id == AV_CODEC_ID_AAC) {
101  bytestream2_skip(&p, 4);
102  size -= 4;
103  }
104  if (size > 52) {
106  size -= 52;
107  ff_alloc_extradata(st->codec, size);
109  }
110  }
111  } else if (bytestream2_peek_byte(&p) == 3) {
112  bytestream2_skip(&p, 7);
113  if (bytestream2_get_bytes_left(&p) > 1)
115  }
116 
117  return 1;
118 }
119 
120 static int
122 {
123  struct ogg *ogg = s->priv_data;
124  struct ogg_stream *os = ogg->streams + idx;
125  AVStream *st = s->streams[idx];
126  uint8_t *p = os->buf + os->pstart;
127  uint32_t t;
128 
129  if(!(*p & 1))
130  return 0;
131  if(*p != 1)
132  return 1;
133 
134  if (os->psize < 100)
135  return AVERROR_INVALIDDATA;
136  t = AV_RL32(p + 96);
137 
138  if(t == 0x05589f80){
139  if (os->psize < 184)
140  return AVERROR_INVALIDDATA;
141 
144  avpriv_set_pts_info(st, 64, AV_RL64(p + 164), 10000000);
145  st->codec->width = AV_RL32(p + 176);
146  st->codec->height = AV_RL32(p + 180);
147  } else if(t == 0x05589f81){
148  if (os->psize < 136)
149  return AVERROR_INVALIDDATA;
150 
153  st->codec->channels = AV_RL16(p + 126);
154  st->codec->sample_rate = AV_RL32(p + 128);
155  st->codec->bit_rate = AV_RL32(p + 132) * 8;
156  }
157 
158  return 1;
159 }
160 
161 static int
163 {
164  struct ogg *ogg = s->priv_data;
165  struct ogg_stream *os = ogg->streams + idx;
166  uint8_t *p = os->buf + os->pstart;
167  int lb;
168 
169  if(*p & 8)
170  os->pflags |= AV_PKT_FLAG_KEY;
171 
172  lb = ((*p & 2) << 1) | ((*p >> 6) & 3);
173  os->pstart += lb + 1;
174  os->psize -= lb + 1;
175 
176  while (lb--)
177  os->pduration += p[lb+1] << (lb*8);
178 
179  return 0;
180 }
181 
183  .magic = "\001video",
184  .magicsize = 6,
185  .header = ogm_header,
186  .packet = ogm_packet,
187  .granule_is_start = 1,
188  .nb_header = 2,
189 };
190 
192  .magic = "\001audio",
193  .magicsize = 6,
194  .header = ogm_header,
195  .packet = ogm_packet,
196  .granule_is_start = 1,
197  .nb_header = 2,
198 };
199 
200 const struct ogg_codec ff_ogm_text_codec = {
201  .magic = "\001text",
202  .magicsize = 5,
203  .header = ogm_header,
204  .packet = ogm_packet,
205  .granule_is_start = 1,
206  .nb_header = 2,
207 };
208 
209 const struct ogg_codec ff_ogm_old_codec = {
210  .magic = "\001Direct Show Samples embedded in Ogg",
211  .magicsize = 35,
212  .header = ogm_dshow_header,
213  .packet = ogm_packet,
214  .granule_is_start = 1,
215  .nb_header = 1,
216 };