oggparseogm.c
Go to the documentation of this file.
1 
25 #include <stdlib.h>
26 #include "libavutil/intreadwrite.h"
27 #include "libavcodec/get_bits.h"
28 #include "libavcodec/bytestream.h"
29 #include "avformat.h"
30 #include "internal.h"
31 #include "oggdec.h"
32 #include "riff.h"
33 
34 static int
36 {
37  struct ogg *ogg = s->priv_data;
38  struct ogg_stream *os = ogg->streams + idx;
39  AVStream *st = s->streams[idx];
41  uint64_t time_unit;
42  uint64_t spu;
43 
44  bytestream2_init(&p, os->buf + os->pstart, os->psize);
45  if (!(bytestream2_peek_byte(&p) & 1))
46  return 0;
47 
48  if (bytestream2_peek_byte(&p) == 1) {
49  bytestream2_skip(&p, 1);
50 
51  if (bytestream2_peek_byte(&p) == 'v'){
52  int tag;
54  bytestream2_skip(&p, 8);
55  tag = bytestream2_get_le32(&p);
57  st->codec->codec_tag = tag;
58  } else if (bytestream2_peek_byte(&p) == 't') {
61  bytestream2_skip(&p, 12);
62  } else {
63  uint8_t acid[5] = { 0 };
64  int cid;
66  bytestream2_skip(&p, 8);
67  bytestream2_get_buffer(&p, acid, 4);
68  acid[4] = 0;
69  cid = strtol(acid, NULL, 16);
72  }
73 
74  bytestream2_skip(&p, 4); /* useless size field */
75 
76  time_unit = bytestream2_get_le64(&p);
77  spu = bytestream2_get_le64(&p);
78  if (!time_unit || !spu) {
79  av_log(s, AV_LOG_ERROR, "Invalid timing values.\n");
80  return AVERROR_INVALIDDATA;
81  }
82 
83  bytestream2_skip(&p, 4); /* default_len */
84  bytestream2_skip(&p, 8); /* buffersize + bits_per_sample */
85 
87  st->codec->width = bytestream2_get_le32(&p);
88  st->codec->height = bytestream2_get_le32(&p);
89  st->codec->time_base.den = spu * 10000000;
90  st->codec->time_base.num = time_unit;
92  } else {
93  st->codec->channels = bytestream2_get_le16(&p);
94  bytestream2_skip(&p, 2); /* block_align */
95  st->codec->bit_rate = bytestream2_get_le32(&p) * 8;
96  st->codec->sample_rate = spu * 10000000 / time_unit;
97  avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
98  }
99  } else if (bytestream2_peek_byte(&p) == 3) {
100  bytestream2_skip(&p, 7);
101  if (bytestream2_get_bytes_left(&p) > 1)
103  }
104 
105  return 1;
106 }
107 
108 static int
110 {
111  struct ogg *ogg = s->priv_data;
112  struct ogg_stream *os = ogg->streams + idx;
113  AVStream *st = s->streams[idx];
114  uint8_t *p = os->buf + os->pstart;
115  uint32_t t;
116 
117  if(!(*p & 1))
118  return 0;
119  if(*p != 1)
120  return 1;
121 
122  t = AV_RL32(p + 96);
123 
124  if(t == 0x05589f80){
127  st->codec->time_base.den = 10000000;
128  st->codec->time_base.num = AV_RL64(p + 164);
129  st->codec->width = AV_RL32(p + 176);
130  st->codec->height = AV_RL32(p + 180);
131  } else if(t == 0x05589f81){
134  st->codec->channels = AV_RL16(p + 126);
135  st->codec->sample_rate = AV_RL32(p + 128);
136  st->codec->bit_rate = AV_RL32(p + 132) * 8;
137  }
138 
139  return 1;
140 }
141 
142 static int
144 {
145  struct ogg *ogg = s->priv_data;
146  struct ogg_stream *os = ogg->streams + idx;
147  uint8_t *p = os->buf + os->pstart;
148  int lb;
149 
150  if(*p & 8)
151  os->pflags |= AV_PKT_FLAG_KEY;
152 
153  lb = ((*p & 2) << 1) | ((*p >> 6) & 3);
154  os->pstart += lb + 1;
155  os->psize -= lb + 1;
156 
157  while (lb--)
158  os->pduration += p[lb+1] << (lb*8);
159 
160  return 0;
161 }
162 
164  .magic = "\001video",
165  .magicsize = 6,
166  .header = ogm_header,
167  .packet = ogm_packet,
168  .granule_is_start = 1,
169 };
170 
172  .magic = "\001audio",
173  .magicsize = 6,
174  .header = ogm_header,
175  .packet = ogm_packet,
176  .granule_is_start = 1,
177 };
178 
179 const struct ogg_codec ff_ogm_text_codec = {
180  .magic = "\001text",
181  .magicsize = 5,
182  .header = ogm_header,
183  .packet = ogm_packet,
184  .granule_is_start = 1,
185 };
186 
187 const struct ogg_codec ff_ogm_old_codec = {
188  .magic = "\001Direct Show Samples embedded in Ogg",
189  .magicsize = 35,
190  .header = ogm_dshow_header,
191  .packet = ogm_packet,
192  .granule_is_start = 1,
193 };