annotate oggparseogm.c @ 1407:fb4bf3858f77 libavformat

Make read_packet fail is the v4l2 driver returns an unexpected frame size (driver's bug? If not, we will have to support this in some way)
author lucabe
date Sun, 22 Oct 2006 09:56:08 +0000
parents 6a5e58d2114b
children c2ad35fbbd30
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1076
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
1 /**
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
2 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
3
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
4 Permission is hereby granted, free of charge, to any person
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
5 obtaining a copy of this software and associated documentation
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
6 files (the "Software"), to deal in the Software without
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
7 restriction, including without limitation the rights to use, copy,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
8 modify, merge, publish, distribute, sublicense, and/or sell copies
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
9 of the Software, and to permit persons to whom the Software is
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
10 furnished to do so, subject to the following conditions:
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
11
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
12 The above copyright notice and this permission notice shall be
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
13 included in all copies or substantial portions of the Software.
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
14
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
22 DEALINGS IN THE SOFTWARE.
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
23 **/
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
24
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
25 #include <stdlib.h>
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
26 #include "avformat.h"
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
27 #include "bitstream.h"
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
28 #include "bswap.h"
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
29 #include "ogg2.h"
1172
6a5e58d2114b move common stuff from avienc.c and wav.c to new file riff.c
mru
parents: 1077
diff changeset
30 #include "riff.h"
1076
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
31
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
32 static int
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
33 ogm_header(AVFormatContext *s, int idx)
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
34 {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
35 ogg_t *ogg = s->priv_data;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
36 ogg_stream_t *os = ogg->streams + idx;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
37 AVStream *st = s->streams[idx];
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
38 uint8_t *p = os->buf + os->pstart;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
39 uint64_t time_unit;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
40 uint64_t spu;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
41 uint32_t default_len;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
42
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
43 if(!(*p & 1))
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
44 return 0;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
45 if(*p != 1)
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
46 return 1;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
47
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
48 p++;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
49
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
50 if(*p == 'v'){
1077
91677ac6fb19 set stream time_base properly
mru
parents: 1076
diff changeset
51 int tag;
1076
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
52 st->codec->codec_type = CODEC_TYPE_VIDEO;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
53 p += 8;
1077
91677ac6fb19 set stream time_base properly
mru
parents: 1076
diff changeset
54 tag = le2me_32(unaligned32(p));
91677ac6fb19 set stream time_base properly
mru
parents: 1076
diff changeset
55 st->codec->codec_id = codec_get_bmp_id(tag);
91677ac6fb19 set stream time_base properly
mru
parents: 1076
diff changeset
56 st->codec->codec_tag = tag;
1076
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
57 } else {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
58 int cid;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
59 st->codec->codec_type = CODEC_TYPE_AUDIO;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
60 p += 8;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
61 p[4] = 0;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
62 cid = strtol(p, NULL, 16);
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
63 st->codec->codec_id = codec_get_wav_id(cid);
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
64 }
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
65
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
66 p += 4;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
67 p += 4; /* useless size field */
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
68
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
69 time_unit = le2me_64(unaligned64(p));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
70 p += 8;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
71 spu = le2me_64(unaligned64(p));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
72 p += 8;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
73 default_len = le2me_32(unaligned32(p));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
74 p += 4;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
75
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
76 p += 8; /* buffersize + bits_per_sample */
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
77
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
78 if(st->codec->codec_type == CODEC_TYPE_VIDEO){
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
79 st->codec->width = le2me_32(unaligned32(p));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
80 p += 4;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
81 st->codec->height = le2me_32(unaligned32(p));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
82 st->codec->time_base.den = spu * 10000000;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
83 st->codec->time_base.num = time_unit;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
84 st->time_base = st->codec->time_base;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
85 } else {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
86 st->codec->channels = le2me_16(unaligned16(p));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
87 p += 2;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
88 p += 2; /* block_align */
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
89 st->codec->bit_rate = le2me_32(unaligned32(p)) * 8;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
90 st->codec->sample_rate = spu * 10000000 / time_unit;
1077
91677ac6fb19 set stream time_base properly
mru
parents: 1076
diff changeset
91 st->time_base.num = 1;
91677ac6fb19 set stream time_base properly
mru
parents: 1076
diff changeset
92 st->time_base.den = st->codec->sample_rate;
1076
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
93 }
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
94
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
95 return 1;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
96 }
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
97
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
98 static int
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
99 ogm_dshow_header(AVFormatContext *s, int idx)
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
100 {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
101 ogg_t *ogg = s->priv_data;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
102 ogg_stream_t *os = ogg->streams + idx;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
103 AVStream *st = s->streams[idx];
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
104 uint8_t *p = os->buf + os->pstart;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
105 uint32_t t;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
106
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
107 if(!(*p & 1))
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
108 return 0;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
109 if(*p != 1)
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
110 return 1;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
111
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
112 t = le2me_32(unaligned32(p + 96));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
113
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
114 if(t == 0x05589f80){
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
115 st->codec->codec_type = CODEC_TYPE_VIDEO;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
116 st->codec->codec_id = codec_get_bmp_id(le2me_32(unaligned32(p + 68)));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
117 st->codec->time_base.den = 10000000;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
118 st->codec->time_base.num = le2me_64(unaligned64(p + 164));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
119 st->codec->width = le2me_32(unaligned32(p + 176));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
120 st->codec->height = le2me_32(unaligned32(p + 180));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
121 } else if(t == 0x05589f81){
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
122 st->codec->codec_type = CODEC_TYPE_AUDIO;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
123 st->codec->codec_id = codec_get_wav_id(le2me_16(unaligned16(p+124)));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
124 st->codec->channels = le2me_16(unaligned16(p + 126));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
125 st->codec->sample_rate = le2me_32(unaligned32(p + 128));
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
126 st->codec->bit_rate = le2me_32(unaligned32(p + 132)) * 8;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
127 }
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
128
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
129 return 1;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
130 }
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
131
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
132 static int
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
133 ogm_packet(AVFormatContext *s, int idx)
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
134 {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
135 ogg_t *ogg = s->priv_data;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
136 ogg_stream_t *os = ogg->streams + idx;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
137 uint8_t *p = os->buf + os->pstart;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
138 int lb;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
139
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
140 lb = ((*p & 2) << 1) | ((*p >> 6) & 3);
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
141 os->pstart += lb + 1;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
142 os->psize -= lb + 1;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
143
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
144 return 0;
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
145 }
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
146
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
147 ogg_codec_t ogm_video_codec = {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
148 .magic = "\001video",
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
149 .magicsize = 6,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
150 .header = ogm_header,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
151 .packet = ogm_packet
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
152 };
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
153
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
154 ogg_codec_t ogm_audio_codec = {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
155 .magic = "\001audio",
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
156 .magicsize = 6,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
157 .header = ogm_header,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
158 .packet = ogm_packet
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
159 };
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
160
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
161 ogg_codec_t ogm_old_codec = {
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
162 .magic = "\001Direct Show Samples embedded in Ogg",
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
163 .magicsize = 35,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
164 .header = ogm_dshow_header,
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
165 .packet = ogm_packet
a1c07ce3943c ogm demuxing
mru
parents:
diff changeset
166 };