Mercurial > libavformat.hg
annotate rmdec.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | f9c75fed4805 |
children | 9a589ae59655 |
rev | line source |
---|---|
0 | 1 /* |
2103 | 2 * "Real" compatible demuxer. |
0 | 3 * Copyright (c) 2000, 2001 Fabrice Bellard. |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1350
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1350
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1350
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1350
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1350
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1350
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
888
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
3286 | 21 |
22 #include "libavutil/avstring.h" | |
0 | 23 #include "avformat.h" |
2103 | 24 #include "rm.h" |
0 | 25 |
2291 | 26 static inline void get_strl(ByteIOContext *pb, char *buf, int buf_size, int len) |
0 | 27 { |
2291 | 28 int i; |
2290
572f7077ba40
Fix get_str/get_str8() to also work if the target string is not long enough to
diego
parents:
2274
diff
changeset
|
29 char *q, r; |
0 | 30 |
31 q = buf; | |
32 for(i=0;i<len;i++) { | |
2290
572f7077ba40
Fix get_str/get_str8() to also work if the target string is not long enough to
diego
parents:
2274
diff
changeset
|
33 r = get_byte(pb); |
0 | 34 if (i < buf_size - 1) |
2290
572f7077ba40
Fix get_str/get_str8() to also work if the target string is not long enough to
diego
parents:
2274
diff
changeset
|
35 *q++ = r; |
0 | 36 } |
2290
572f7077ba40
Fix get_str/get_str8() to also work if the target string is not long enough to
diego
parents:
2274
diff
changeset
|
37 if (buf_size > 0) *q = '\0'; |
0 | 38 } |
39 | |
2291 | 40 static void get_str16(ByteIOContext *pb, char *buf, int buf_size) |
41 { | |
42 get_strl(pb, buf, buf_size, get_be16(pb)); | |
43 } | |
44 | |
0 | 45 static void get_str8(ByteIOContext *pb, char *buf, int buf_size) |
46 { | |
2291 | 47 get_strl(pb, buf, buf_size, get_byte(pb)); |
0 | 48 } |
49 | |
1106 | 50 static int rm_read_audio_stream_info(AVFormatContext *s, AVStream *st, |
194 | 51 int read_all) |
52 { | |
879 | 53 RMContext *rm = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
54 ByteIOContext *pb = s->pb; |
886
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
55 char buf[256]; |
194 | 56 uint32_t version; |
57 int i; | |
58 | |
59 /* ra type header */ | |
60 version = get_be32(pb); /* version */ | |
61 if (((version >> 16) & 0xff) == 3) { | |
886
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
62 int64_t startpos = url_ftell(pb); |
194 | 63 /* very old version */ |
64 for(i = 0; i < 14; i++) | |
65 get_byte(pb); | |
66 get_str8(pb, s->title, sizeof(s->title)); | |
67 get_str8(pb, s->author, sizeof(s->author)); | |
68 get_str8(pb, s->copyright, sizeof(s->copyright)); | |
69 get_str8(pb, s->comment, sizeof(s->comment)); | |
886
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
70 if ((startpos + (version & 0xffff)) >= url_ftell(pb) + 2) { |
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
71 // fourcc (should always be "lpcJ") |
194 | 72 get_byte(pb); |
73 get_str8(pb, buf, sizeof(buf)); | |
886
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
74 } |
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
75 // Skip extra header crap (this should never happen) |
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
76 if ((startpos + (version & 0xffff)) > url_ftell(pb)) |
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
77 url_fskip(pb, (version & 0xffff) + startpos - url_ftell(pb)); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
78 st->codec->sample_rate = 8000; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
79 st->codec->channels = 1; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
80 st->codec->codec_type = CODEC_TYPE_AUDIO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
81 st->codec->codec_id = CODEC_ID_RA_144; |
194 | 82 } else { |
879 | 83 int flavor, sub_packet_h, coded_framesize, sub_packet_size; |
194 | 84 /* old version (4) */ |
85 get_be32(pb); /* .ra4 */ | |
687
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
86 get_be32(pb); /* data size */ |
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
87 get_be16(pb); /* version2 */ |
194 | 88 get_be32(pb); /* header size */ |
687
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
89 flavor= get_be16(pb); /* add codec info / flavor */ |
879 | 90 rm->coded_framesize = coded_framesize = get_be32(pb); /* coded frame size */ |
194 | 91 get_be32(pb); /* ??? */ |
92 get_be32(pb); /* ??? */ | |
93 get_be32(pb); /* ??? */ | |
885 | 94 rm->sub_packet_h = sub_packet_h = get_be16(pb); /* 1 */ |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
95 st->codec->block_align= get_be16(pb); /* frame size */ |
879 | 96 rm->sub_packet_size = sub_packet_size = get_be16(pb); /* sub packet size */ |
687
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
97 get_be16(pb); /* ??? */ |
879 | 98 if (((version >> 16) & 0xff) == 5) { |
99 get_be16(pb); get_be16(pb); get_be16(pb); } | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
100 st->codec->sample_rate = get_be16(pb); |
194 | 101 get_be32(pb); |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
102 st->codec->channels = get_be16(pb); |
879 | 103 if (((version >> 16) & 0xff) == 5) { |
104 get_be32(pb); | |
887 | 105 buf[0] = get_byte(pb); |
106 buf[1] = get_byte(pb); | |
107 buf[2] = get_byte(pb); | |
108 buf[3] = get_byte(pb); | |
109 buf[4] = 0; | |
110 } else { | |
1441
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
111 get_str8(pb, buf, sizeof(buf)); /* desc */ |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
112 get_str8(pb, buf, sizeof(buf)); /* desc */ |
887 | 113 } |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
114 st->codec->codec_type = CODEC_TYPE_AUDIO; |
194 | 115 if (!strcmp(buf, "dnet")) { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
116 st->codec->codec_id = CODEC_ID_AC3; |
2585
ecd8a9aa182d
dnet audio needs avparser to work with the lavc ac3 decoder.
rtogni
parents:
2532
diff
changeset
|
117 st->need_parsing = AVSTREAM_PARSE_FULL; |
687
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
118 } else if (!strcmp(buf, "28_8")) { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
119 st->codec->codec_id = CODEC_ID_RA_288; |
879 | 120 st->codec->extradata_size= 0; |
121 rm->audio_framesize = st->codec->block_align; | |
122 st->codec->block_align = coded_framesize; | |
1079 | 123 |
124 if(rm->audio_framesize >= UINT_MAX / sub_packet_h){ | |
125 av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); | |
126 return -1; | |
127 } | |
128 | |
879 | 129 rm->audiobuf = av_malloc(rm->audio_framesize * sub_packet_h); |
2024 | 130 } else if ((!strcmp(buf, "cook")) || (!strcmp(buf, "atrc"))) { |
879 | 131 int codecdata_length, i; |
132 get_be16(pb); get_byte(pb); | |
133 if (((version >> 16) & 0xff) == 5) | |
134 get_byte(pb); | |
135 codecdata_length = get_be32(pb); | |
1079 | 136 if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ |
137 av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); | |
138 return -1; | |
139 } | |
140 | |
2024 | 141 if (!strcmp(buf, "cook")) st->codec->codec_id = CODEC_ID_COOK; |
142 else st->codec->codec_id = CODEC_ID_ATRAC3; | |
879 | 143 st->codec->extradata_size= codecdata_length; |
884
2ece9c9dd94c
malloc padding to avoid reading past the malloc()ed area.
henry
parents:
879
diff
changeset
|
144 st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
879 | 145 for(i = 0; i < codecdata_length; i++) |
146 ((uint8_t*)st->codec->extradata)[i] = get_byte(pb); | |
147 rm->audio_framesize = st->codec->block_align; | |
148 st->codec->block_align = rm->sub_packet_size; | |
1079 | 149 |
150 if(rm->audio_framesize >= UINT_MAX / sub_packet_h){ | |
151 av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); | |
152 return -1; | |
153 } | |
154 | |
879 | 155 rm->audiobuf = av_malloc(rm->audio_framesize * sub_packet_h); |
1105 | 156 } else if (!strcmp(buf, "raac") || !strcmp(buf, "racp")) { |
157 int codecdata_length, i; | |
158 get_be16(pb); get_byte(pb); | |
159 if (((version >> 16) & 0xff) == 5) | |
160 get_byte(pb); | |
161 st->codec->codec_id = CODEC_ID_AAC; | |
162 codecdata_length = get_be32(pb); | |
1106 | 163 if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ |
164 av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); | |
165 return -1; | |
166 } | |
1105 | 167 if (codecdata_length >= 1) { |
168 st->codec->extradata_size = codecdata_length - 1; | |
169 st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
170 get_byte(pb); | |
171 for(i = 0; i < st->codec->extradata_size; i++) | |
172 ((uint8_t*)st->codec->extradata)[i] = get_byte(pb); | |
173 } | |
194 | 174 } else { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
175 st->codec->codec_id = CODEC_ID_NONE; |
2189 | 176 av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name)); |
194 | 177 } |
178 if (read_all) { | |
179 get_byte(pb); | |
180 get_byte(pb); | |
181 get_byte(pb); | |
885 | 182 |
194 | 183 get_str8(pb, s->title, sizeof(s->title)); |
184 get_str8(pb, s->author, sizeof(s->author)); | |
185 get_str8(pb, s->copyright, sizeof(s->copyright)); | |
186 get_str8(pb, s->comment, sizeof(s->comment)); | |
187 } | |
188 } | |
1106 | 189 return 0; |
194 | 190 } |
191 | |
2889 | 192 int |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
193 ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVStream *st) |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
194 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
195 ByteIOContext *pb = s->pb; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
196 unsigned int v; |
2719
6469205c08e4
Change ff_rm_read_mdpr_codecdata to get back to old behavior.
benoit
parents:
2707
diff
changeset
|
197 int codec_data_size, size; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
198 int64_t codec_pos; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
199 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
200 codec_data_size = get_be32(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
201 codec_pos = url_ftell(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
202 v = get_be32(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
203 if (v == MKTAG(0xfd, 'a', 'r', '.')) { |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
204 /* ra type header */ |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
205 if (rm_read_audio_stream_info(s, st, 0)) |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
206 return -1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
207 } else { |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
208 int fps, fps2; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
209 if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) { |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
210 fail1: |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
211 av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n"); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
212 goto skip; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
213 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
214 st->codec->codec_tag = get_le32(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
215 // av_log(NULL, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0')); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
216 if ( st->codec->codec_tag != MKTAG('R', 'V', '1', '0') |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
217 && st->codec->codec_tag != MKTAG('R', 'V', '2', '0') |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
218 && st->codec->codec_tag != MKTAG('R', 'V', '3', '0') |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
219 && st->codec->codec_tag != MKTAG('R', 'V', '4', '0')) |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
220 goto fail1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
221 st->codec->width = get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
222 st->codec->height = get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
223 st->codec->time_base.num= 1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
224 fps= get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
225 st->codec->codec_type = CODEC_TYPE_VIDEO; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
226 get_be32(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
227 fps2= get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
228 get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
229 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
230 st->codec->extradata_size= codec_data_size - (url_ftell(pb) - codec_pos); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
231 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
232 if(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){ |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
233 //check is redundant as get_buffer() will catch this |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
234 av_log(s, AV_LOG_ERROR, "st->codec->extradata_size too large\n"); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
235 return -1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
236 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
237 st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
3410
18239c59049b
Check whether the memory allocation for extradata succeeded. Fixes issue 472.
takis
parents:
3286
diff
changeset
|
238 if (!st->codec->extradata) |
18239c59049b
Check whether the memory allocation for extradata succeeded. Fixes issue 472.
takis
parents:
3286
diff
changeset
|
239 return AVERROR(ENOMEM); |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
240 get_buffer(pb, st->codec->extradata, st->codec->extradata_size); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
241 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
242 // av_log(NULL, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
243 st->codec->time_base.den = fps * st->codec->time_base.num; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
244 switch(((uint8_t*)st->codec->extradata)[4]>>4){ |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
245 case 1: st->codec->codec_id = CODEC_ID_RV10; break; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
246 case 2: st->codec->codec_id = CODEC_ID_RV20; break; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
247 case 3: st->codec->codec_id = CODEC_ID_RV30; break; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
248 case 4: st->codec->codec_id = CODEC_ID_RV40; break; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
249 default: goto fail1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
250 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
251 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
252 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
253 skip: |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
254 /* skip codec info */ |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
255 size = url_ftell(pb) - codec_pos; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
256 url_fskip(pb, codec_data_size - size); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
257 |
2719
6469205c08e4
Change ff_rm_read_mdpr_codecdata to get back to old behavior.
benoit
parents:
2707
diff
changeset
|
258 return 0; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
259 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
260 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
261 |
194 | 262 static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) |
263 { | |
264 RMContext *rm = s->priv_data; | |
265 AVStream *st; | |
266 | |
267 rm->old_format = 1; | |
268 st = av_new_stream(s, 0); | |
269 if (!st) | |
1106 | 270 return -1; |
271 return rm_read_audio_stream_info(s, st, 1); | |
194 | 272 } |
273 | |
0 | 274 static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) |
275 { | |
276 RMContext *rm = s->priv_data; | |
277 AVStream *st; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
278 ByteIOContext *pb = s->pb; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
279 unsigned int tag; |
3497 | 280 int tag_size; |
1350
f77cf5a063a8
Remove unused variables and the corresponding warnings along with them.
diego
parents:
1344
diff
changeset
|
281 unsigned int start_time, duration; |
0 | 282 char buf[128]; |
283 int flags = 0; | |
284 | |
194 | 285 tag = get_le32(pb); |
286 if (tag == MKTAG('.', 'r', 'a', 0xfd)) { | |
287 /* very old .ra format */ | |
288 return rm_read_header_old(s, ap); | |
289 } else if (tag != MKTAG('.', 'R', 'M', 'F')) { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
290 return AVERROR(EIO); |
194 | 291 } |
0 | 292 |
293 get_be32(pb); /* header size */ | |
294 get_be16(pb); | |
295 get_be32(pb); | |
296 get_be32(pb); /* number of headers */ | |
885 | 297 |
0 | 298 for(;;) { |
299 if (url_feof(pb)) | |
3486 | 300 return -1; |
0 | 301 tag = get_le32(pb); |
302 tag_size = get_be32(pb); | |
303 get_be16(pb); | |
304 #if 0 | |
885 | 305 printf("tag=%c%c%c%c (%08x) size=%d\n", |
0 | 306 (tag) & 0xff, |
307 (tag >> 8) & 0xff, | |
308 (tag >> 16) & 0xff, | |
309 (tag >> 24) & 0xff, | |
310 tag, | |
311 tag_size); | |
312 #endif | |
736 | 313 if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A')) |
3486 | 314 return -1; |
0 | 315 switch(tag) { |
316 case MKTAG('P', 'R', 'O', 'P'): | |
317 /* file header */ | |
318 get_be32(pb); /* max bit rate */ | |
319 get_be32(pb); /* avg bit rate */ | |
320 get_be32(pb); /* max packet size */ | |
321 get_be32(pb); /* avg packet size */ | |
322 get_be32(pb); /* nb packets */ | |
323 get_be32(pb); /* duration */ | |
324 get_be32(pb); /* preroll */ | |
325 get_be32(pb); /* index offset */ | |
326 get_be32(pb); /* data offset */ | |
327 get_be16(pb); /* nb streams */ | |
328 flags = get_be16(pb); /* flags */ | |
329 break; | |
330 case MKTAG('C', 'O', 'N', 'T'): | |
2291 | 331 get_str16(pb, s->title, sizeof(s->title)); |
332 get_str16(pb, s->author, sizeof(s->author)); | |
333 get_str16(pb, s->copyright, sizeof(s->copyright)); | |
334 get_str16(pb, s->comment, sizeof(s->comment)); | |
0 | 335 break; |
336 case MKTAG('M', 'D', 'P', 'R'): | |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
85
diff
changeset
|
337 st = av_new_stream(s, 0); |
0 | 338 if (!st) |
3486 | 339 return AVERROR(ENOMEM); |
0 | 340 st->id = get_be16(pb); |
341 get_be32(pb); /* max bit rate */ | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
342 st->codec->bit_rate = get_be32(pb); /* bit rate */ |
0 | 343 get_be32(pb); /* max packet size */ |
344 get_be32(pb); /* avg packet size */ | |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
85
diff
changeset
|
345 start_time = get_be32(pb); /* start time */ |
0 | 346 get_be32(pb); /* preroll */ |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
85
diff
changeset
|
347 duration = get_be32(pb); /* duration */ |
743 | 348 st->start_time = start_time; |
349 st->duration = duration; | |
0 | 350 get_str8(pb, buf, sizeof(buf)); /* desc */ |
351 get_str8(pb, buf, sizeof(buf)); /* mimetype */ | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
352 st->codec->codec_type = CODEC_TYPE_DATA; |
607 | 353 av_set_pts_info(st, 64, 1, 1000); |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
354 if (ff_rm_read_mdpr_codecdata(s, st) < 0) |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
355 return -1; |
0 | 356 break; |
357 case MKTAG('D', 'A', 'T', 'A'): | |
358 goto header_end; | |
359 default: | |
360 /* unknown tag: skip it */ | |
361 url_fskip(pb, tag_size - 10); | |
362 break; | |
363 } | |
364 } | |
365 header_end: | |
366 rm->nb_packets = get_be32(pb); /* number of packets */ | |
367 if (!rm->nb_packets && (flags & 4)) | |
368 rm->nb_packets = 3600 * 25; | |
369 get_be32(pb); /* next data header */ | |
2653 | 370 rm->curpic_num = -1; |
0 | 371 return 0; |
372 } | |
373 | |
374 static int get_num(ByteIOContext *pb, int *len) | |
375 { | |
376 int n, n1; | |
377 | |
378 n = get_be16(pb); | |
379 (*len)-=2; | |
2791
5d0fecceff17
Revert r10892, it's wrong and no longer needed to prevent crashes
rtogni
parents:
2771
diff
changeset
|
380 n &= 0x7FFF; |
0 | 381 if (n >= 0x4000) { |
382 return n - 0x4000; | |
383 } else { | |
384 n1 = get_be16(pb); | |
385 (*len)-=2; | |
386 return (n << 16) | n1; | |
387 } | |
388 } | |
389 | |
194 | 390 /* multiple of 20 bytes for ra144 (ugly) */ |
391 #define RAW_PACKET_SIZE 1000 | |
392 | |
613 | 393 static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){ |
612 | 394 RMContext *rm = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
395 ByteIOContext *pb = s->pb; |
612 | 396 int len, num, res, i; |
397 AVStream *st; | |
632 | 398 uint32_t state=0xFFFFFFFF; |
612 | 399 |
400 while(!url_feof(pb)){ | |
3207 | 401 *pos= url_ftell(pb) - 3; |
612 | 402 if(rm->remaining_len > 0){ |
403 num= rm->current_stream; | |
404 len= rm->remaining_len; | |
405 *timestamp = AV_NOPTS_VALUE; | |
406 *flags= 0; | |
407 }else{ | |
632 | 408 state= (state<<8) + get_byte(pb); |
885 | 409 |
632 | 410 if(state == MKBETAG('I', 'N', 'D', 'X')){ |
411 len = get_be16(pb) - 6; | |
412 if(len<0) | |
413 continue; | |
414 goto skip; | |
415 } | |
885 | 416 |
632 | 417 if(state > (unsigned)0xFFFF || state < 12) |
612 | 418 continue; |
632 | 419 len=state; |
420 state= 0xFFFFFFFF; | |
421 | |
612 | 422 num = get_be16(pb); |
423 *timestamp = get_be32(pb); | |
424 res= get_byte(pb); /* reserved */ | |
425 *flags = get_byte(pb); /* flags */ | |
613 | 426 |
885 | 427 |
612 | 428 len -= 12; |
429 } | |
430 for(i=0;i<s->nb_streams;i++) { | |
431 st = s->streams[i]; | |
432 if (num == st->id) | |
433 break; | |
434 } | |
435 if (i == s->nb_streams) { | |
632 | 436 skip: |
612 | 437 /* skip packet if unknown number */ |
438 url_fskip(pb, len); | |
439 rm->remaining_len -= len; | |
440 continue; | |
441 } | |
442 *stream_index= i; | |
885 | 443 |
612 | 444 return len; |
445 } | |
446 return -1; | |
447 } | |
448 | |
2653 | 449 static int rm_assemble_video_frame(AVFormatContext *s, RMContext *rm, AVPacket *pkt, int len) |
450 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
451 ByteIOContext *pb = s->pb; |
2653 | 452 int hdr, seq, pic_num, len2, pos; |
453 int type; | |
454 | |
455 hdr = get_byte(pb); len--; | |
456 type = hdr >> 6; | |
457 switch(type){ | |
458 case 0: // slice | |
459 case 2: // last slice | |
460 seq = get_byte(pb); len--; | |
461 len2 = get_num(pb, &len); | |
462 pos = get_num(pb, &len); | |
463 pic_num = get_byte(pb); len--; | |
464 rm->remaining_len = len; | |
465 break; | |
466 case 1: //whole frame | |
467 seq = get_byte(pb); len--; | |
468 if(av_new_packet(pkt, len + 9) < 0) | |
469 return AVERROR(EIO); | |
470 pkt->data[0] = 0; | |
471 AV_WL32(pkt->data + 1, 1); | |
472 AV_WL32(pkt->data + 5, 0); | |
473 get_buffer(pb, pkt->data + 9, len); | |
474 rm->remaining_len = 0; | |
475 return 0; | |
476 case 3: //frame as a part of packet | |
477 len2 = get_num(pb, &len); | |
478 pos = get_num(pb, &len); | |
479 pic_num = get_byte(pb); len--; | |
480 rm->remaining_len = len - len2; | |
481 if(av_new_packet(pkt, len2 + 9) < 0) | |
482 return AVERROR(EIO); | |
483 pkt->data[0] = 0; | |
484 AV_WL32(pkt->data + 1, 1); | |
485 AV_WL32(pkt->data + 5, 0); | |
486 get_buffer(pb, pkt->data + 9, len2); | |
487 return 0; | |
488 } | |
489 //now we have to deal with single slice | |
490 | |
491 if((seq & 0x7F) == 1 || rm->curpic_num != pic_num){ | |
492 rm->slices = ((hdr & 0x3F) << 1) + 1; | |
2764 | 493 rm->videobufsize = len2 + 8*rm->slices + 1; |
2770
a7e42cf4b364
Replace realloc with free+malloc, the previous content of the buffer is
rtogni
parents:
2766
diff
changeset
|
494 av_free(rm->videobuf); |
a7e42cf4b364
Replace realloc with free+malloc, the previous content of the buffer is
rtogni
parents:
2766
diff
changeset
|
495 if(!(rm->videobuf = av_malloc(rm->videobufsize))) |
2763 | 496 return AVERROR(ENOMEM); |
2653 | 497 rm->videobufpos = 8*rm->slices + 1; |
498 rm->cur_slice = 0; | |
499 rm->curpic_num = pic_num; | |
2696 | 500 rm->pktpos = url_ftell(pb); |
2653 | 501 } |
2766 | 502 if(type == 2) |
2653 | 503 len = FFMIN(len, pos); |
504 | |
2754 | 505 if(++rm->cur_slice > rm->slices) |
2653 | 506 return 1; |
507 AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1); | |
508 AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1); | |
509 if(rm->videobufpos + len > rm->videobufsize) | |
510 return 1; | |
511 if (get_buffer(pb, rm->videobuf + rm->videobufpos, len) != len) | |
512 return AVERROR(EIO); | |
2808 | 513 rm->videobufpos += len; |
2653 | 514 rm->remaining_len-= len; |
515 | |
516 if(type == 2 || (rm->videobufpos) == rm->videobufsize){ | |
517 rm->videobuf[0] = rm->cur_slice-1; | |
2762
137eec75e3df
Optimize memory management to create an av_packet from multiple slices:
rtogni
parents:
2754
diff
changeset
|
518 if(av_new_packet(pkt, rm->videobufpos - 8*(rm->slices - rm->cur_slice)) < 0) |
2653 | 519 return AVERROR(ENOMEM); |
2762
137eec75e3df
Optimize memory management to create an av_packet from multiple slices:
rtogni
parents:
2754
diff
changeset
|
520 memcpy(pkt->data, rm->videobuf, 1 + 8*rm->cur_slice); |
2766 | 521 memcpy(pkt->data + 1 + 8*rm->cur_slice, rm->videobuf + 1 + 8*rm->slices, |
522 rm->videobufpos - 1 - 8*rm->slices); | |
2696 | 523 pkt->pts = AV_NOPTS_VALUE; |
524 pkt->pos = rm->pktpos; | |
2653 | 525 return 0; |
526 } | |
527 | |
528 return 1; | |
529 } | |
530 | |
2725 | 531 static inline void |
532 rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt) | |
533 { | |
534 uint8_t *ptr; | |
535 int j; | |
536 | |
537 if (st->codec->codec_id == CODEC_ID_AC3) { | |
538 ptr = pkt->data; | |
539 for (j=0;j<pkt->size;j+=2) { | |
540 FFSWAP(int, ptr[0], ptr[1]); | |
541 ptr += 2; | |
542 } | |
543 } | |
544 } | |
545 | |
2889 | 546 int |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
547 ff_rm_parse_packet (AVFormatContext *s, AVStream *st, int len, AVPacket *pkt, |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
548 int *seq, int *flags, int64_t *timestamp) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
549 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
550 ByteIOContext *pb = s->pb; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
551 RMContext *rm = s->priv_data; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
552 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
553 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
554 rm->current_stream= st->id; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
555 if(rm_assemble_video_frame(s, rm, pkt, len) == 1) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
556 return -1; //got partial frame |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
557 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
558 if ((st->codec->codec_id == CODEC_ID_RA_288) || |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
559 (st->codec->codec_id == CODEC_ID_COOK) || |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
560 (st->codec->codec_id == CODEC_ID_ATRAC3)) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
561 int x; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
562 int sps = rm->sub_packet_size; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
563 int cfs = rm->coded_framesize; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
564 int h = rm->sub_packet_h; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
565 int y = rm->sub_packet_cnt; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
566 int w = rm->audio_framesize; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
567 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
568 if (*flags & 2) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
569 y = rm->sub_packet_cnt = 0; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
570 if (!y) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
571 rm->audiotimestamp = *timestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
572 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
573 switch(st->codec->codec_id) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
574 case CODEC_ID_RA_288: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
575 for (x = 0; x < h/2; x++) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
576 get_buffer(pb, rm->audiobuf+x*2*w+y*cfs, cfs); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
577 break; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
578 case CODEC_ID_ATRAC3: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
579 case CODEC_ID_COOK: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
580 for (x = 0; x < w/sps; x++) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
581 get_buffer(pb, rm->audiobuf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
582 break; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
583 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
584 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
585 if (++(rm->sub_packet_cnt) < h) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
586 return -1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
587 else { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
588 rm->sub_packet_cnt = 0; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
589 rm->audio_stream_num = st->index; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
590 rm->audio_pkt_cnt = h * w / st->codec->block_align - 1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
591 // Release first audio packet |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
592 av_new_packet(pkt, st->codec->block_align); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
593 memcpy(pkt->data, rm->audiobuf, st->codec->block_align); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
594 *timestamp = rm->audiotimestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
595 *flags = 2; // Mark first packet as keyframe |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
596 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
597 } else if (st->codec->codec_id == CODEC_ID_AAC) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
598 int x; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
599 rm->audio_stream_num = st->index; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
600 rm->sub_packet_cnt = (get_be16(pb) & 0xf0) >> 4; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
601 if (rm->sub_packet_cnt) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
602 for (x = 0; x < rm->sub_packet_cnt; x++) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
603 rm->sub_packet_lengths[x] = get_be16(pb); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
604 // Release first audio packet |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
605 rm->audio_pkt_cnt = rm->sub_packet_cnt - 1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
606 av_get_packet(pb, pkt, rm->sub_packet_lengths[0]); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
607 *flags = 2; // Mark first packet as keyframe |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
608 } |
2940 | 609 } else { |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
610 av_get_packet(pb, pkt, len); |
2753
b55dad23bfcb
Move dnet-ac3 byte-swapping code close to audio packet read code
rtogni
parents:
2725
diff
changeset
|
611 rm_ac3_swap_bytes(st, pkt); |
2940 | 612 } |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
613 } else |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
614 av_get_packet(pb, pkt, len); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
615 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
616 if( (st->discard >= AVDISCARD_NONKEY && !(*flags&2)) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
617 || st->discard >= AVDISCARD_ALL){ |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
618 av_free_packet(pkt); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
619 return -1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
620 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
621 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
622 pkt->stream_index = st->index; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
623 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
624 #if 0 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
625 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
626 if(st->codec->codec_id == CODEC_ID_RV20){ |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
627 int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
628 av_log(NULL, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
629 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
630 seq |= (*timestamp&~0x3FFF); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
631 if(seq - *timestamp > 0x2000) seq -= 0x4000; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
632 if(seq - *timestamp < -0x2000) seq += 0x4000; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
633 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
634 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
635 #endif |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
636 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
637 pkt->pts= *timestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
638 if (*flags & 2) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
639 pkt->flags |= PKT_FLAG_KEY; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
640 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
641 return 0; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
642 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
643 |
2889 | 644 void |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
645 ff_rm_retrieve_cache (AVFormatContext *s, AVStream *st, AVPacket *pkt) |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
646 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
647 ByteIOContext *pb = s->pb; |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
648 RMContext *rm = s->priv_data; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
649 |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
650 assert (rm->audio_pkt_cnt > 0); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
651 |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
652 if (st->codec->codec_id == CODEC_ID_AAC) |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
653 av_get_packet(pb, pkt, rm->sub_packet_lengths[rm->sub_packet_cnt - rm->audio_pkt_cnt]); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
654 else { |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
655 av_new_packet(pkt, st->codec->block_align); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
656 memcpy(pkt->data, rm->audiobuf + st->codec->block_align * |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
657 (rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt), |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
658 st->codec->block_align); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
659 } |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
660 rm->audio_pkt_cnt--; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
661 pkt->flags = 0; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
662 pkt->stream_index = st->index; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
663 } |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
664 |
0 | 665 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) |
666 { | |
667 RMContext *rm = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
668 ByteIOContext *pb = s->pb; |
0 | 669 AVStream *st; |
2725 | 670 int i, len; |
613 | 671 int64_t timestamp, pos; |
612 | 672 int flags; |
0 | 673 |
888 | 674 if (rm->audio_pkt_cnt) { |
879 | 675 // If there are queued audio packet return them first |
676 st = s->streams[rm->audio_stream_num]; | |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
677 ff_rm_retrieve_cache(s, st, pkt); |
888 | 678 } else if (rm->old_format) { |
679 st = s->streams[0]; | |
680 if (st->codec->codec_id == CODEC_ID_RA_288) { | |
681 int x, y; | |
682 | |
683 for (y = 0; y < rm->sub_packet_h; y++) | |
684 for (x = 0; x < rm->sub_packet_h/2; x++) | |
685 if (get_buffer(pb, rm->audiobuf+x*2*rm->audio_framesize+y*rm->coded_framesize, rm->coded_framesize) <= 0) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
686 return AVERROR(EIO); |
888 | 687 rm->audio_stream_num = 0; |
688 rm->audio_pkt_cnt = rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - 1; | |
689 // Release first audio packet | |
690 av_new_packet(pkt, st->codec->block_align); | |
691 memcpy(pkt->data, rm->audiobuf, st->codec->block_align); | |
692 pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe | |
693 pkt->stream_index = 0; | |
694 } else { | |
695 /* just read raw bytes */ | |
696 len = RAW_PACKET_SIZE; | |
697 len= av_get_packet(pb, pkt, len); | |
698 pkt->stream_index = 0; | |
699 if (len <= 0) { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
700 return AVERROR(EIO); |
888 | 701 } |
702 pkt->size = len; | |
703 } | |
2753
b55dad23bfcb
Move dnet-ac3 byte-swapping code close to audio packet read code
rtogni
parents:
2725
diff
changeset
|
704 rm_ac3_swap_bytes(st, pkt); |
194 | 705 } else { |
613 | 706 int seq=1; |
652 | 707 resync: |
613 | 708 len=sync(s, ×tamp, &flags, &i, &pos); |
612 | 709 if(len<0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
710 return AVERROR(EIO); |
612 | 711 st = s->streams[i]; |
712 | |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
713 if (ff_rm_parse_packet (s, st, len, pkt, &seq, &flags, ×tamp) < 0) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
714 goto resync; |
879 | 715 |
2937
f3070076d901
Remove some spaces to keep certain people's eyes from hurting.
diego
parents:
2904
diff
changeset
|
716 if((flags&2) && (seq&0x7F) == 1) |
2883 | 717 av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME); |
0 | 718 } |
719 | |
720 return 0; | |
721 } | |
722 | |
723 static int rm_read_close(AVFormatContext *s) | |
724 { | |
879 | 725 RMContext *rm = s->priv_data; |
726 | |
727 av_free(rm->audiobuf); | |
2653 | 728 av_free(rm->videobuf); |
0 | 729 return 0; |
730 } | |
731 | |
732 static int rm_probe(AVProbeData *p) | |
733 { | |
734 /* check file header */ | |
194 | 735 if ((p->buf[0] == '.' && p->buf[1] == 'R' && |
736 p->buf[2] == 'M' && p->buf[3] == 'F' && | |
737 p->buf[4] == 0 && p->buf[5] == 0) || | |
738 (p->buf[0] == '.' && p->buf[1] == 'r' && | |
739 p->buf[2] == 'a' && p->buf[3] == 0xfd)) | |
0 | 740 return AVPROBE_SCORE_MAX; |
741 else | |
742 return 0; | |
743 } | |
744 | |
885 | 745 static int64_t rm_read_dts(AVFormatContext *s, int stream_index, |
612 | 746 int64_t *ppos, int64_t pos_limit) |
747 { | |
748 RMContext *rm = s->priv_data; | |
749 int64_t pos, dts; | |
613 | 750 int stream_index2, flags, len, h; |
612 | 751 |
752 pos = *ppos; | |
885 | 753 |
612 | 754 if(rm->old_format) |
755 return AV_NOPTS_VALUE; | |
756 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
757 url_fseek(s->pb, pos, SEEK_SET); |
612 | 758 rm->remaining_len=0; |
759 for(;;){ | |
613 | 760 int seq=1; |
761 AVStream *st; | |
762 | |
763 len=sync(s, &dts, &flags, &stream_index2, &pos); | |
612 | 764 if(len<0) |
765 return AV_NOPTS_VALUE; | |
613 | 766 |
767 st = s->streams[stream_index2]; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
768 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
769 h= get_byte(s->pb); len--; |
613 | 770 if(!(h & 0x40)){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
771 seq = get_byte(s->pb); len--; |
612 | 772 } |
773 } | |
885 | 774 |
613 | 775 if((flags&2) && (seq&0x7F) == 1){ |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1441
diff
changeset
|
776 // av_log(s, AV_LOG_DEBUG, "%d %d-%d %"PRId64" %d\n", flags, stream_index2, stream_index, dts, seq); |
979 | 777 av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME); |
613 | 778 if(stream_index2 == stream_index) |
779 break; | |
780 } | |
781 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
782 url_fskip(s->pb, len); |
612 | 783 } |
784 *ppos = pos; | |
785 return dts; | |
786 } | |
787 | |
1169 | 788 AVInputFormat rm_demuxer = { |
0 | 789 "rm", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3410
diff
changeset
|
790 NULL_IF_CONFIG_SMALL("RM format"), |
0 | 791 sizeof(RMContext), |
792 rm_probe, | |
793 rm_read_header, | |
794 rm_read_packet, | |
795 rm_read_close, | |
612 | 796 NULL, |
797 rm_read_dts, | |
0 | 798 }; |