Mercurial > libavformat.hg
annotate rmdec.c @ 3902:5f9bec099c69 libavformat
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
in rtpdec.c, so that they can be shared and used in the same way in rtsp.c.
The handlers, since they are specific for RDT, are registered in rdt.c and
a new registration function is thus called from allformats.c.
The dynamic payload handler also implements RDT-specific SDP-line parsing for
OpaqueData and StartTime, which are specific for RDT and needed for proper
playback. OpaqueData contains one or a list ("MLTI") of "MDPR" chunks that
can be parsed by the rmdec.c function ff_rm_read_mdpr_codecdata(). To use
this function, we create a new rdt_demuxer, which has the same private data
as the rm_demuxer. The resulting AVFormatContext created with _open_stream()
can thus be used to call functions in the RM demuxer.
See discussion in "Realmedia patch" thread on ML.
author | rbultje |
---|---|
date | Sun, 07 Sep 2008 01:21:24 +0000 |
parents | d50c5556cb82 |
children | 77b99eddf88a |
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 |
3873
9a589ae59655
Use chunk-size in function calling mdpr_read_codecdata() rather than in the
rbultje
parents:
3497
diff
changeset
|
193 ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVStream *st, int codec_data_size) |
2707
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; |
3873
9a589ae59655
Use chunk-size in function calling mdpr_read_codecdata() rather than in the
rbultje
parents:
3497
diff
changeset
|
197 int 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 |
3874
d50c5556cb82
Move av_set_pts_info() inside the mdpr_read_codecdata() call, so that it is
rbultje
parents:
3873
diff
changeset
|
200 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
|
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; |
3873
9a589ae59655
Use chunk-size in function calling mdpr_read_codecdata() rather than in the
rbultje
parents:
3497
diff
changeset
|
353 if (ff_rm_read_mdpr_codecdata(s, st, get_be32(pb)) < 0) |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
354 return -1; |
0 | 355 break; |
356 case MKTAG('D', 'A', 'T', 'A'): | |
357 goto header_end; | |
358 default: | |
359 /* unknown tag: skip it */ | |
360 url_fskip(pb, tag_size - 10); | |
361 break; | |
362 } | |
363 } | |
364 header_end: | |
365 rm->nb_packets = get_be32(pb); /* number of packets */ | |
366 if (!rm->nb_packets && (flags & 4)) | |
367 rm->nb_packets = 3600 * 25; | |
368 get_be32(pb); /* next data header */ | |
2653 | 369 rm->curpic_num = -1; |
0 | 370 return 0; |
371 } | |
372 | |
373 static int get_num(ByteIOContext *pb, int *len) | |
374 { | |
375 int n, n1; | |
376 | |
377 n = get_be16(pb); | |
378 (*len)-=2; | |
2791
5d0fecceff17
Revert r10892, it's wrong and no longer needed to prevent crashes
rtogni
parents:
2771
diff
changeset
|
379 n &= 0x7FFF; |
0 | 380 if (n >= 0x4000) { |
381 return n - 0x4000; | |
382 } else { | |
383 n1 = get_be16(pb); | |
384 (*len)-=2; | |
385 return (n << 16) | n1; | |
386 } | |
387 } | |
388 | |
194 | 389 /* multiple of 20 bytes for ra144 (ugly) */ |
390 #define RAW_PACKET_SIZE 1000 | |
391 | |
613 | 392 static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){ |
612 | 393 RMContext *rm = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
394 ByteIOContext *pb = s->pb; |
612 | 395 int len, num, res, i; |
396 AVStream *st; | |
632 | 397 uint32_t state=0xFFFFFFFF; |
612 | 398 |
399 while(!url_feof(pb)){ | |
3207 | 400 *pos= url_ftell(pb) - 3; |
612 | 401 if(rm->remaining_len > 0){ |
402 num= rm->current_stream; | |
403 len= rm->remaining_len; | |
404 *timestamp = AV_NOPTS_VALUE; | |
405 *flags= 0; | |
406 }else{ | |
632 | 407 state= (state<<8) + get_byte(pb); |
885 | 408 |
632 | 409 if(state == MKBETAG('I', 'N', 'D', 'X')){ |
410 len = get_be16(pb) - 6; | |
411 if(len<0) | |
412 continue; | |
413 goto skip; | |
414 } | |
885 | 415 |
632 | 416 if(state > (unsigned)0xFFFF || state < 12) |
612 | 417 continue; |
632 | 418 len=state; |
419 state= 0xFFFFFFFF; | |
420 | |
612 | 421 num = get_be16(pb); |
422 *timestamp = get_be32(pb); | |
423 res= get_byte(pb); /* reserved */ | |
424 *flags = get_byte(pb); /* flags */ | |
613 | 425 |
885 | 426 |
612 | 427 len -= 12; |
428 } | |
429 for(i=0;i<s->nb_streams;i++) { | |
430 st = s->streams[i]; | |
431 if (num == st->id) | |
432 break; | |
433 } | |
434 if (i == s->nb_streams) { | |
632 | 435 skip: |
612 | 436 /* skip packet if unknown number */ |
437 url_fskip(pb, len); | |
438 rm->remaining_len -= len; | |
439 continue; | |
440 } | |
441 *stream_index= i; | |
885 | 442 |
612 | 443 return len; |
444 } | |
445 return -1; | |
446 } | |
447 | |
2653 | 448 static int rm_assemble_video_frame(AVFormatContext *s, RMContext *rm, AVPacket *pkt, int len) |
449 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
450 ByteIOContext *pb = s->pb; |
2653 | 451 int hdr, seq, pic_num, len2, pos; |
452 int type; | |
453 | |
454 hdr = get_byte(pb); len--; | |
455 type = hdr >> 6; | |
456 switch(type){ | |
457 case 0: // slice | |
458 case 2: // last slice | |
459 seq = get_byte(pb); len--; | |
460 len2 = get_num(pb, &len); | |
461 pos = get_num(pb, &len); | |
462 pic_num = get_byte(pb); len--; | |
463 rm->remaining_len = len; | |
464 break; | |
465 case 1: //whole frame | |
466 seq = get_byte(pb); len--; | |
467 if(av_new_packet(pkt, len + 9) < 0) | |
468 return AVERROR(EIO); | |
469 pkt->data[0] = 0; | |
470 AV_WL32(pkt->data + 1, 1); | |
471 AV_WL32(pkt->data + 5, 0); | |
472 get_buffer(pb, pkt->data + 9, len); | |
473 rm->remaining_len = 0; | |
474 return 0; | |
475 case 3: //frame as a part of packet | |
476 len2 = get_num(pb, &len); | |
477 pos = get_num(pb, &len); | |
478 pic_num = get_byte(pb); len--; | |
479 rm->remaining_len = len - len2; | |
480 if(av_new_packet(pkt, len2 + 9) < 0) | |
481 return AVERROR(EIO); | |
482 pkt->data[0] = 0; | |
483 AV_WL32(pkt->data + 1, 1); | |
484 AV_WL32(pkt->data + 5, 0); | |
485 get_buffer(pb, pkt->data + 9, len2); | |
486 return 0; | |
487 } | |
488 //now we have to deal with single slice | |
489 | |
490 if((seq & 0x7F) == 1 || rm->curpic_num != pic_num){ | |
491 rm->slices = ((hdr & 0x3F) << 1) + 1; | |
2764 | 492 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
|
493 av_free(rm->videobuf); |
a7e42cf4b364
Replace realloc with free+malloc, the previous content of the buffer is
rtogni
parents:
2766
diff
changeset
|
494 if(!(rm->videobuf = av_malloc(rm->videobufsize))) |
2763 | 495 return AVERROR(ENOMEM); |
2653 | 496 rm->videobufpos = 8*rm->slices + 1; |
497 rm->cur_slice = 0; | |
498 rm->curpic_num = pic_num; | |
2696 | 499 rm->pktpos = url_ftell(pb); |
2653 | 500 } |
2766 | 501 if(type == 2) |
2653 | 502 len = FFMIN(len, pos); |
503 | |
2754 | 504 if(++rm->cur_slice > rm->slices) |
2653 | 505 return 1; |
506 AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1); | |
507 AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1); | |
508 if(rm->videobufpos + len > rm->videobufsize) | |
509 return 1; | |
510 if (get_buffer(pb, rm->videobuf + rm->videobufpos, len) != len) | |
511 return AVERROR(EIO); | |
2808 | 512 rm->videobufpos += len; |
2653 | 513 rm->remaining_len-= len; |
514 | |
515 if(type == 2 || (rm->videobufpos) == rm->videobufsize){ | |
516 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
|
517 if(av_new_packet(pkt, rm->videobufpos - 8*(rm->slices - rm->cur_slice)) < 0) |
2653 | 518 return AVERROR(ENOMEM); |
2762
137eec75e3df
Optimize memory management to create an av_packet from multiple slices:
rtogni
parents:
2754
diff
changeset
|
519 memcpy(pkt->data, rm->videobuf, 1 + 8*rm->cur_slice); |
2766 | 520 memcpy(pkt->data + 1 + 8*rm->cur_slice, rm->videobuf + 1 + 8*rm->slices, |
521 rm->videobufpos - 1 - 8*rm->slices); | |
2696 | 522 pkt->pts = AV_NOPTS_VALUE; |
523 pkt->pos = rm->pktpos; | |
2653 | 524 return 0; |
525 } | |
526 | |
527 return 1; | |
528 } | |
529 | |
2725 | 530 static inline void |
531 rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt) | |
532 { | |
533 uint8_t *ptr; | |
534 int j; | |
535 | |
536 if (st->codec->codec_id == CODEC_ID_AC3) { | |
537 ptr = pkt->data; | |
538 for (j=0;j<pkt->size;j+=2) { | |
539 FFSWAP(int, ptr[0], ptr[1]); | |
540 ptr += 2; | |
541 } | |
542 } | |
543 } | |
544 | |
2889 | 545 int |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
546 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
|
547 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
|
548 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
549 ByteIOContext *pb = s->pb; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
550 RMContext *rm = s->priv_data; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
551 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
552 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
|
553 rm->current_stream= st->id; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
554 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
|
555 return -1; //got partial frame |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
556 } 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
|
557 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
|
558 (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
|
559 (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
|
560 int x; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
561 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
|
562 int cfs = rm->coded_framesize; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
563 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
|
564 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
|
565 int w = rm->audio_framesize; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
566 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
567 if (*flags & 2) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
568 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
|
569 if (!y) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
570 rm->audiotimestamp = *timestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
571 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
572 switch(st->codec->codec_id) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
573 case CODEC_ID_RA_288: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
574 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
|
575 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
|
576 break; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
577 case CODEC_ID_ATRAC3: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
578 case CODEC_ID_COOK: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
579 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
|
580 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
|
581 break; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
582 } |
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 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
|
585 return -1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
586 else { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
587 rm->sub_packet_cnt = 0; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
588 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
|
589 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
|
590 // Release first audio packet |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
591 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
|
592 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
|
593 *timestamp = rm->audiotimestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
594 *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
|
595 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
596 } 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
|
597 int x; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
598 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
|
599 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
|
600 if (rm->sub_packet_cnt) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
601 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
|
602 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
|
603 // Release first audio packet |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
604 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
|
605 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
|
606 *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
|
607 } |
2940 | 608 } else { |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
609 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
|
610 rm_ac3_swap_bytes(st, pkt); |
2940 | 611 } |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
612 } else |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
613 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
|
614 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
615 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
|
616 || st->discard >= AVDISCARD_ALL){ |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
617 av_free_packet(pkt); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
618 return -1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
619 } |
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 pkt->stream_index = st->index; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
622 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
623 #if 0 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
624 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
|
625 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
|
626 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
|
627 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
|
628 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
629 seq |= (*timestamp&~0x3FFF); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
630 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
|
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 } |
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 #endif |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
635 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
636 pkt->pts= *timestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
637 if (*flags & 2) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
638 pkt->flags |= PKT_FLAG_KEY; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
639 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
640 return 0; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
641 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
642 |
2889 | 643 void |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
644 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
|
645 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
646 ByteIOContext *pb = s->pb; |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
647 RMContext *rm = s->priv_data; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
648 |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
649 assert (rm->audio_pkt_cnt > 0); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
650 |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
651 if (st->codec->codec_id == CODEC_ID_AAC) |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
652 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
|
653 else { |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
654 av_new_packet(pkt, st->codec->block_align); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
655 memcpy(pkt->data, rm->audiobuf + st->codec->block_align * |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
656 (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
|
657 st->codec->block_align); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
658 } |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
659 rm->audio_pkt_cnt--; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
660 pkt->flags = 0; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
661 pkt->stream_index = st->index; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
662 } |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
663 |
0 | 664 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) |
665 { | |
666 RMContext *rm = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
667 ByteIOContext *pb = s->pb; |
0 | 668 AVStream *st; |
2725 | 669 int i, len; |
613 | 670 int64_t timestamp, pos; |
612 | 671 int flags; |
0 | 672 |
888 | 673 if (rm->audio_pkt_cnt) { |
879 | 674 // If there are queued audio packet return them first |
675 st = s->streams[rm->audio_stream_num]; | |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
676 ff_rm_retrieve_cache(s, st, pkt); |
888 | 677 } else if (rm->old_format) { |
678 st = s->streams[0]; | |
679 if (st->codec->codec_id == CODEC_ID_RA_288) { | |
680 int x, y; | |
681 | |
682 for (y = 0; y < rm->sub_packet_h; y++) | |
683 for (x = 0; x < rm->sub_packet_h/2; x++) | |
684 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
|
685 return AVERROR(EIO); |
888 | 686 rm->audio_stream_num = 0; |
687 rm->audio_pkt_cnt = rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - 1; | |
688 // Release first audio packet | |
689 av_new_packet(pkt, st->codec->block_align); | |
690 memcpy(pkt->data, rm->audiobuf, st->codec->block_align); | |
691 pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe | |
692 pkt->stream_index = 0; | |
693 } else { | |
694 /* just read raw bytes */ | |
695 len = RAW_PACKET_SIZE; | |
696 len= av_get_packet(pb, pkt, len); | |
697 pkt->stream_index = 0; | |
698 if (len <= 0) { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
699 return AVERROR(EIO); |
888 | 700 } |
701 pkt->size = len; | |
702 } | |
2753
b55dad23bfcb
Move dnet-ac3 byte-swapping code close to audio packet read code
rtogni
parents:
2725
diff
changeset
|
703 rm_ac3_swap_bytes(st, pkt); |
194 | 704 } else { |
613 | 705 int seq=1; |
652 | 706 resync: |
613 | 707 len=sync(s, ×tamp, &flags, &i, &pos); |
612 | 708 if(len<0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
709 return AVERROR(EIO); |
612 | 710 st = s->streams[i]; |
711 | |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
712 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
|
713 goto resync; |
879 | 714 |
2937
f3070076d901
Remove some spaces to keep certain people's eyes from hurting.
diego
parents:
2904
diff
changeset
|
715 if((flags&2) && (seq&0x7F) == 1) |
2883 | 716 av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME); |
0 | 717 } |
718 | |
719 return 0; | |
720 } | |
721 | |
722 static int rm_read_close(AVFormatContext *s) | |
723 { | |
879 | 724 RMContext *rm = s->priv_data; |
725 | |
726 av_free(rm->audiobuf); | |
2653 | 727 av_free(rm->videobuf); |
0 | 728 return 0; |
729 } | |
730 | |
731 static int rm_probe(AVProbeData *p) | |
732 { | |
733 /* check file header */ | |
194 | 734 if ((p->buf[0] == '.' && p->buf[1] == 'R' && |
735 p->buf[2] == 'M' && p->buf[3] == 'F' && | |
736 p->buf[4] == 0 && p->buf[5] == 0) || | |
737 (p->buf[0] == '.' && p->buf[1] == 'r' && | |
738 p->buf[2] == 'a' && p->buf[3] == 0xfd)) | |
0 | 739 return AVPROBE_SCORE_MAX; |
740 else | |
741 return 0; | |
742 } | |
743 | |
885 | 744 static int64_t rm_read_dts(AVFormatContext *s, int stream_index, |
612 | 745 int64_t *ppos, int64_t pos_limit) |
746 { | |
747 RMContext *rm = s->priv_data; | |
748 int64_t pos, dts; | |
613 | 749 int stream_index2, flags, len, h; |
612 | 750 |
751 pos = *ppos; | |
885 | 752 |
612 | 753 if(rm->old_format) |
754 return AV_NOPTS_VALUE; | |
755 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
756 url_fseek(s->pb, pos, SEEK_SET); |
612 | 757 rm->remaining_len=0; |
758 for(;;){ | |
613 | 759 int seq=1; |
760 AVStream *st; | |
761 | |
762 len=sync(s, &dts, &flags, &stream_index2, &pos); | |
612 | 763 if(len<0) |
764 return AV_NOPTS_VALUE; | |
613 | 765 |
766 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
|
767 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
768 h= get_byte(s->pb); len--; |
613 | 769 if(!(h & 0x40)){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
770 seq = get_byte(s->pb); len--; |
612 | 771 } |
772 } | |
885 | 773 |
613 | 774 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
|
775 // av_log(s, AV_LOG_DEBUG, "%d %d-%d %"PRId64" %d\n", flags, stream_index2, stream_index, dts, seq); |
979 | 776 av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME); |
613 | 777 if(stream_index2 == stream_index) |
778 break; | |
779 } | |
780 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
781 url_fskip(s->pb, len); |
612 | 782 } |
783 *ppos = pos; | |
784 return dts; | |
785 } | |
786 | |
1169 | 787 AVInputFormat rm_demuxer = { |
0 | 788 "rm", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3410
diff
changeset
|
789 NULL_IF_CONFIG_SMALL("RM format"), |
0 | 790 sizeof(RMContext), |
791 rm_probe, | |
792 rm_read_header, | |
793 rm_read_packet, | |
794 rm_read_close, | |
612 | 795 NULL, |
796 rm_read_dts, | |
0 | 797 }; |
3902
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
798 |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
799 AVInputFormat rdt_demuxer = { |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
800 "rdt", |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
801 NULL_IF_CONFIG_SMALL("RDT demuxer"), |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
802 sizeof(RMContext), |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
803 NULL, NULL, NULL, rm_read_close, NULL, NULL |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
804 }; |