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  bytestream2_skip(&p, 4); /* default_len */
79  bytestream2_skip(&p, 8); /* buffersize + bits_per_sample */
80 
82  st->codec->width = bytestream2_get_le32(&p);
83  st->codec->height = bytestream2_get_le32(&p);
84  avpriv_set_pts_info(st, 64, time_unit, spu * 10000000);
85  } else {
86  st->codec->channels = bytestream2_get_le16(&p);
87  bytestream2_skip(&p, 2); /* block_align */
88  st->codec->bit_rate = bytestream2_get_le32(&p) * 8;
89  st->codec->sample_rate = spu * 10000000 / time_unit;
90  avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
91  }
92  } else if (bytestream2_peek_byte(&p) == 3) {
93  bytestream2_skip(&p, 7);
94  if (bytestream2_get_bytes_left(&p) > 1)
96  }
97 
98  return 1;
99 }
100 
101 static int
103 {
104  struct ogg *ogg = s->priv_data;
105  struct ogg_stream *os = ogg->streams + idx;
106  AVStream *st = s->streams[idx];
107  uint8_t *p = os->buf + os->pstart;
108  uint32_t t;
109 
110  if(!(*p & 1))
111  return 0;
112  if(*p != 1)
113  return 1;
114 
115  t = AV_RL32(p + 96);
116 
117  if(t == 0x05589f80){
120  avpriv_set_pts_info(st, 64, AV_RL64(p + 164), 10000000);
121  st->codec->width = AV_RL32(p + 176);
122  st->codec->height = AV_RL32(p + 180);
123  } else if(t == 0x05589f81){
126  st->codec->channels = AV_RL16(p + 126);
127  st->codec->sample_rate = AV_RL32(p + 128);
128  st->codec->bit_rate = AV_RL32(p + 132) * 8;
129  }
130 
131  return 1;
132 }
133 
134 static int
136 {
137  struct ogg *ogg = s->priv_data;
138  struct ogg_stream *os = ogg->streams + idx;
139  uint8_t *p = os->buf + os->pstart;
140  int lb;
141 
142  if(*p & 8)
143  os->pflags |= AV_PKT_FLAG_KEY;
144 
145  lb = ((*p & 2) << 1) | ((*p >> 6) & 3);
146  os->pstart += lb + 1;
147  os->psize -= lb + 1;
148 
149  while (lb--)
150  os->pduration += p[lb+1] << (lb*8);
151 
152  return 0;
153 }
154 
156  .magic = "\001video",
157  .magicsize = 6,
158  .header = ogm_header,
159  .packet = ogm_packet,
160  .granule_is_start = 1,
161  .nb_header = 2,
162 };
163 
165  .magic = "\001audio",
166  .magicsize = 6,
167  .header = ogm_header,
168  .packet = ogm_packet,
169  .granule_is_start = 1,
170  .nb_header = 2,
171 };
172 
173 const struct ogg_codec ff_ogm_text_codec = {
174  .magic = "\001text",
175  .magicsize = 5,
176  .header = ogm_header,
177  .packet = ogm_packet,
178  .granule_is_start = 1,
179  .nb_header = 2,
180 };
181 
182 const struct ogg_codec ff_ogm_old_codec = {
183  .magic = "\001Direct Show Samples embedded in Ogg",
184  .magicsize = 35,
185  .header = ogm_dshow_header,
186  .packet = ogm_packet,
187  .granule_is_start = 1,
188  .nb_header = 1,
189 };