Mercurial > libavformat.hg
annotate rmdec.c @ 4723:a2390c6a35e6 libavformat
Fix index generation in the way that it was supposed to be used. See the
discussion in the ML thread "[PATCH] rmdec.c: merge old/new packet reading
code".
Over time, this code broke somewhat, e.g. seq was never actually written
into (and was thus always 1, therefore the seq condition was always true),
whereas it was supposed to be set to the sequence number of the video slice
in case the video frame is divided over multiple RM packets (slices). The
problem of this is that packets other than those containing the beginning
of a video frame would be indexed as well.
Secondly, flags&2 is supposed to be true for video keyframes and for these
audio packets containing the start of a block. For some codecs (e.g. AAC),
that is every single packet, whereas for others (e.g. cook), that is the
packet containing the first of a series of scrambled packets that are to be
descrambled together. Indexing any of the following would lead to incomplete
and thus useless frames. Problem here is that flags would be reset to 2 to
indicate that the first packet is ready to be returned, and in addition if
no data was left to be returned (which is always true for the first packet),
then we wouldn't actually write the index entry anyway.
All in all, the idea was good and it probably worked at some point, but that
is long ago. This patch should at the very least make it likely for this code
to be executed again at the right times, i.e. the way it was originally
intended to be used.
author | rbultje |
---|---|
date | Sun, 15 Mar 2009 20:14:25 +0000 |
parents | 4de640349078 |
children | 0d7a569678a4 |
rev | line source |
---|---|
0 | 1 /* |
2103 | 2 * "Real" compatible demuxer. |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4201
diff
changeset
|
3 * Copyright (c) 2000, 2001 Fabrice Bellard |
0 | 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" | |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
4173
diff
changeset
|
23 #include "libavutil/intreadwrite.h" |
0 | 24 #include "avformat.h" |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
25 #include "rm.h" |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
26 |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
27 struct RMStream { |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
28 AVPacket pkt; ///< place to store merged video frame / reordered audio data |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
29 int videobufsize; ///< current assembled frame size |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
30 int videobufpos; ///< position for the next slice in the video buffer |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
31 int curpic_num; ///< picture number of current frame |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
32 int cur_slice, slices; |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
33 int64_t pktpos; ///< first slice position in file |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
34 /// Audio descrambling matrix parameters |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
35 int64_t audiotimestamp; ///< Audio packet timestamp |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
36 int sub_packet_cnt; // Subpacket counter, used while reading |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
37 int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
38 int audio_framesize; /// Audio frame size from container |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
39 int sub_packet_lengths[16]; /// Length of each subpacket |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
40 }; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
41 |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
42 typedef struct { |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
43 int nb_packets; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
44 int old_format; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
45 int current_stream; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
46 int remaining_len; |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
47 int audio_stream_num; ///< Stream number for audio packets |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
48 int audio_pkt_cnt; ///< Output packet counter |
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
49 } RMDemuxContext; |
0 | 50 |
2291 | 51 static inline void get_strl(ByteIOContext *pb, char *buf, int buf_size, int len) |
0 | 52 { |
2291 | 53 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
|
54 char *q, r; |
0 | 55 |
56 q = buf; | |
57 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
|
58 r = get_byte(pb); |
0 | 59 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
|
60 *q++ = r; |
0 | 61 } |
2290
572f7077ba40
Fix get_str/get_str8() to also work if the target string is not long enough to
diego
parents:
2274
diff
changeset
|
62 if (buf_size > 0) *q = '\0'; |
0 | 63 } |
64 | |
65 static void get_str8(ByteIOContext *pb, char *buf, int buf_size) | |
66 { | |
2291 | 67 get_strl(pb, buf, buf_size, get_byte(pb)); |
0 | 68 } |
69 | |
4522 | 70 static void rm_read_metadata(AVFormatContext *s, int wide) |
71 { | |
72 char buf[1024]; | |
73 int i; | |
74 for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) { | |
75 int len = wide ? get_be16(s->pb) : get_byte(s->pb); | |
76 get_strl(s->pb, buf, sizeof(buf), len); | |
77 av_metadata_set(&s->metadata, ff_rm_metadata[i], buf); | |
78 } | |
79 } | |
80 | |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
81 RMStream *ff_rm_alloc_rmstream (void) |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
82 { |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
83 RMStream *rms = av_mallocz(sizeof(RMStream)); |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
84 rms->curpic_num = -1; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
85 return rms; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
86 } |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
87 |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
88 void ff_rm_free_rmstream (RMStream *rms) |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
89 { |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
90 av_free_packet(&rms->pkt); |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
91 } |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
92 |
4036
1349c277efbd
Add ByteIOContext argument to public ff_rm_* functions so that we can
rbultje
parents:
4014
diff
changeset
|
93 static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
94 AVStream *st, RMStream *ast, int read_all) |
194 | 95 { |
886
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
96 char buf[256]; |
194 | 97 uint32_t version; |
98 | |
99 /* ra type header */ | |
100 version = get_be32(pb); /* version */ | |
101 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
|
102 int64_t startpos = url_ftell(pb); |
4111
eed7d267ef66
Use get_buffer() and url_fskip() for some loops of get_byte()s. See discussion in ML thread
rbultje
parents:
4110
diff
changeset
|
103 url_fskip(pb, 14); |
4522 | 104 rm_read_metadata(s, 0); |
886
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
105 if ((startpos + (version & 0xffff)) >= url_ftell(pb) + 2) { |
4075 | 106 // fourcc (should always be "lpcJ") |
107 get_byte(pb); | |
108 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
|
109 } |
7ed1351f8c7e
Fix for Real "old" files version 3 with no 4cc. Fixes thankyou144.ra
rtognimp
parents:
885
diff
changeset
|
110 // 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
|
111 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
|
112 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
|
113 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
|
114 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
|
115 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
|
116 st->codec->codec_id = CODEC_ID_RA_144; |
194 | 117 } else { |
879 | 118 int flavor, sub_packet_h, coded_framesize, sub_packet_size; |
194 | 119 /* old version (4) */ |
120 get_be32(pb); /* .ra4 */ | |
687
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
121 get_be32(pb); /* data size */ |
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
122 get_be16(pb); /* version2 */ |
194 | 123 get_be32(pb); /* header size */ |
687
561f27e36bc4
ra288 demuxing support (doesnt really work, might be demuxer or decoder bug)
michael
parents:
652
diff
changeset
|
124 flavor= get_be16(pb); /* add codec info / flavor */ |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
125 ast->coded_framesize = coded_framesize = get_be32(pb); /* coded frame size */ |
194 | 126 get_be32(pb); /* ??? */ |
127 get_be32(pb); /* ??? */ | |
128 get_be32(pb); /* ??? */ | |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
129 ast->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
|
130 st->codec->block_align= get_be16(pb); /* frame size */ |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
131 ast->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
|
132 get_be16(pb); /* ??? */ |
879 | 133 if (((version >> 16) & 0xff) == 5) { |
4110 | 134 get_be16(pb); get_be16(pb); get_be16(pb); |
135 } | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
136 st->codec->sample_rate = get_be16(pb); |
194 | 137 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
|
138 st->codec->channels = get_be16(pb); |
879 | 139 if (((version >> 16) & 0xff) == 5) { |
140 get_be32(pb); | |
4111
eed7d267ef66
Use get_buffer() and url_fskip() for some loops of get_byte()s. See discussion in ML thread
rbultje
parents:
4110
diff
changeset
|
141 get_buffer(pb, buf, 4); |
887 | 142 buf[4] = 0; |
143 } else { | |
1441
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
144 get_str8(pb, buf, sizeof(buf)); /* desc */ |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1415
diff
changeset
|
145 get_str8(pb, buf, sizeof(buf)); /* desc */ |
887 | 146 } |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
775
diff
changeset
|
147 st->codec->codec_type = CODEC_TYPE_AUDIO; |
194 | 148 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
|
149 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
|
150 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
|
151 } 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
|
152 st->codec->codec_id = CODEC_ID_RA_288; |
879 | 153 st->codec->extradata_size= 0; |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
154 ast->audio_framesize = st->codec->block_align; |
879 | 155 st->codec->block_align = coded_framesize; |
1079 | 156 |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
157 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
158 av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); |
1079 | 159 return -1; |
160 } | |
161 | |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
162 av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); |
3945 | 163 } else if ((!strcmp(buf, "cook")) || (!strcmp(buf, "atrc")) || (!strcmp(buf, "sipr"))) { |
4111
eed7d267ef66
Use get_buffer() and url_fskip() for some loops of get_byte()s. See discussion in ML thread
rbultje
parents:
4110
diff
changeset
|
164 int codecdata_length; |
879 | 165 get_be16(pb); get_byte(pb); |
166 if (((version >> 16) & 0xff) == 5) | |
167 get_byte(pb); | |
168 codecdata_length = get_be32(pb); | |
1079 | 169 if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ |
170 av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); | |
171 return -1; | |
172 } | |
173 | |
4014
2e7994e45100
Check sub_packet_size against 0 to avoid div by zero later.
michael
parents:
3945
diff
changeset
|
174 if(sub_packet_size <= 0){ |
2e7994e45100
Check sub_packet_size against 0 to avoid div by zero later.
michael
parents:
3945
diff
changeset
|
175 av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); |
2e7994e45100
Check sub_packet_size against 0 to avoid div by zero later.
michael
parents:
3945
diff
changeset
|
176 return -1; |
2e7994e45100
Check sub_packet_size against 0 to avoid div by zero later.
michael
parents:
3945
diff
changeset
|
177 } |
2e7994e45100
Check sub_packet_size against 0 to avoid div by zero later.
michael
parents:
3945
diff
changeset
|
178 |
2024 | 179 if (!strcmp(buf, "cook")) st->codec->codec_id = CODEC_ID_COOK; |
3945 | 180 else if (!strcmp(buf, "sipr")) st->codec->codec_id = CODEC_ID_SIPR; |
2024 | 181 else st->codec->codec_id = CODEC_ID_ATRAC3; |
879 | 182 st->codec->extradata_size= codecdata_length; |
884
2ece9c9dd94c
malloc padding to avoid reading past the malloc()ed area.
henry
parents:
879
diff
changeset
|
183 st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
4111
eed7d267ef66
Use get_buffer() and url_fskip() for some loops of get_byte()s. See discussion in ML thread
rbultje
parents:
4110
diff
changeset
|
184 get_buffer(pb, st->codec->extradata, st->codec->extradata_size); |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
185 ast->audio_framesize = st->codec->block_align; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
186 st->codec->block_align = ast->sub_packet_size; |
1079 | 187 |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
188 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ |
1079 | 189 av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); |
190 return -1; | |
191 } | |
192 | |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
193 av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h); |
1105 | 194 } else if (!strcmp(buf, "raac") || !strcmp(buf, "racp")) { |
4111
eed7d267ef66
Use get_buffer() and url_fskip() for some loops of get_byte()s. See discussion in ML thread
rbultje
parents:
4110
diff
changeset
|
195 int codecdata_length; |
1105 | 196 get_be16(pb); get_byte(pb); |
197 if (((version >> 16) & 0xff) == 5) | |
198 get_byte(pb); | |
199 st->codec->codec_id = CODEC_ID_AAC; | |
200 codecdata_length = get_be32(pb); | |
1106 | 201 if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){ |
202 av_log(s, AV_LOG_ERROR, "codecdata_length too large\n"); | |
203 return -1; | |
204 } | |
1105 | 205 if (codecdata_length >= 1) { |
206 st->codec->extradata_size = codecdata_length - 1; | |
207 st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
208 get_byte(pb); | |
4111
eed7d267ef66
Use get_buffer() and url_fskip() for some loops of get_byte()s. See discussion in ML thread
rbultje
parents:
4110
diff
changeset
|
209 get_buffer(pb, st->codec->extradata, st->codec->extradata_size); |
1105 | 210 } |
194 | 211 } 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
|
212 st->codec->codec_id = CODEC_ID_NONE; |
2189 | 213 av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name)); |
194 | 214 } |
215 if (read_all) { | |
216 get_byte(pb); | |
217 get_byte(pb); | |
218 get_byte(pb); | |
4522 | 219 rm_read_metadata(s, 0); |
194 | 220 } |
221 } | |
1106 | 222 return 0; |
194 | 223 } |
224 | |
2889 | 225 int |
4036
1349c277efbd
Add ByteIOContext argument to public ff_rm_* functions so that we can
rbultje
parents:
4014
diff
changeset
|
226 ff_rm_read_mdpr_codecdata (AVFormatContext *s, ByteIOContext *pb, |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
227 AVStream *st, RMStream *rst, int codec_data_size) |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
228 { |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
229 unsigned int v; |
3873
9a589ae59655
Use chunk-size in function calling mdpr_read_codecdata() rather than in the
rbultje
parents:
3497
diff
changeset
|
230 int size; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
231 int64_t codec_pos; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
232 |
3874
d50c5556cb82
Move av_set_pts_info() inside the mdpr_read_codecdata() call, so that it is
rbultje
parents:
3873
diff
changeset
|
233 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
|
234 codec_pos = url_ftell(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
235 v = get_be32(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
236 if (v == MKTAG(0xfd, 'a', 'r', '.')) { |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
237 /* ra type header */ |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
238 if (rm_read_audio_stream_info(s, pb, st, rst, 0)) |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
239 return -1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
240 } else { |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
241 int fps, fps2; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
242 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
|
243 fail1: |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
244 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
|
245 goto skip; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
246 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
247 st->codec->codec_tag = get_le32(pb); |
4511 | 248 // av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0')); |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
249 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
|
250 && 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
|
251 && st->codec->codec_tag != MKTAG('R', 'V', '3', '0') |
3930 | 252 && st->codec->codec_tag != MKTAG('R', 'V', '4', '0') |
253 && st->codec->codec_tag != MKTAG('R', 'V', 'T', 'R')) | |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
254 goto fail1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
255 st->codec->width = get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
256 st->codec->height = get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
257 st->codec->time_base.num= 1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
258 fps= get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
259 st->codec->codec_type = CODEC_TYPE_VIDEO; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
260 get_be32(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
261 fps2= get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
262 get_be16(pb); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
263 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
264 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
|
265 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
266 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
|
267 //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
|
268 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
|
269 return -1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
270 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
271 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
|
272 if (!st->codec->extradata) |
18239c59049b
Check whether the memory allocation for extradata succeeded. Fixes issue 472.
takis
parents:
3286
diff
changeset
|
273 return AVERROR(ENOMEM); |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
274 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
|
275 |
4511 | 276 // av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
277 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
|
278 switch(((uint8_t*)st->codec->extradata)[4]>>4){ |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
279 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
|
280 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
|
281 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
|
282 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
|
283 default: goto fail1; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
284 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
285 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
286 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
287 skip: |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
288 /* skip codec info */ |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
289 size = url_ftell(pb) - codec_pos; |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
290 url_fskip(pb, codec_data_size - size); |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
291 |
2719
6469205c08e4
Change ff_rm_read_mdpr_codecdata to get back to old behavior.
benoit
parents:
2707
diff
changeset
|
292 return 0; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
293 } |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
294 |
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
295 |
194 | 296 static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) |
297 { | |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
298 RMDemuxContext *rm = s->priv_data; |
194 | 299 AVStream *st; |
300 | |
301 rm->old_format = 1; | |
302 st = av_new_stream(s, 0); | |
303 if (!st) | |
1106 | 304 return -1; |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
305 st->priv_data = ff_rm_alloc_rmstream(); |
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
306 return rm_read_audio_stream_info(s, s->pb, st, st->priv_data, 1); |
194 | 307 } |
308 | |
0 | 309 static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) |
310 { | |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
311 RMDemuxContext *rm = s->priv_data; |
0 | 312 AVStream *st; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
313 ByteIOContext *pb = s->pb; |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
314 unsigned int tag; |
3497 | 315 int tag_size; |
1350
f77cf5a063a8
Remove unused variables and the corresponding warnings along with them.
diego
parents:
1344
diff
changeset
|
316 unsigned int start_time, duration; |
0 | 317 char buf[128]; |
318 int flags = 0; | |
319 | |
194 | 320 tag = get_le32(pb); |
321 if (tag == MKTAG('.', 'r', 'a', 0xfd)) { | |
322 /* very old .ra format */ | |
323 return rm_read_header_old(s, ap); | |
324 } else if (tag != MKTAG('.', 'R', 'M', 'F')) { | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
325 return AVERROR(EIO); |
194 | 326 } |
0 | 327 |
328 get_be32(pb); /* header size */ | |
329 get_be16(pb); | |
330 get_be32(pb); | |
331 get_be32(pb); /* number of headers */ | |
885 | 332 |
0 | 333 for(;;) { |
334 if (url_feof(pb)) | |
3486 | 335 return -1; |
0 | 336 tag = get_le32(pb); |
337 tag_size = get_be32(pb); | |
338 get_be16(pb); | |
339 #if 0 | |
885 | 340 printf("tag=%c%c%c%c (%08x) size=%d\n", |
0 | 341 (tag) & 0xff, |
342 (tag >> 8) & 0xff, | |
343 (tag >> 16) & 0xff, | |
344 (tag >> 24) & 0xff, | |
345 tag, | |
346 tag_size); | |
347 #endif | |
736 | 348 if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A')) |
3486 | 349 return -1; |
0 | 350 switch(tag) { |
351 case MKTAG('P', 'R', 'O', 'P'): | |
352 /* file header */ | |
353 get_be32(pb); /* max bit rate */ | |
354 get_be32(pb); /* avg bit rate */ | |
355 get_be32(pb); /* max packet size */ | |
356 get_be32(pb); /* avg packet size */ | |
357 get_be32(pb); /* nb packets */ | |
358 get_be32(pb); /* duration */ | |
359 get_be32(pb); /* preroll */ | |
360 get_be32(pb); /* index offset */ | |
361 get_be32(pb); /* data offset */ | |
362 get_be16(pb); /* nb streams */ | |
363 flags = get_be16(pb); /* flags */ | |
364 break; | |
365 case MKTAG('C', 'O', 'N', 'T'): | |
4522 | 366 rm_read_metadata(s, 1); |
0 | 367 break; |
368 case MKTAG('M', 'D', 'P', 'R'): | |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
85
diff
changeset
|
369 st = av_new_stream(s, 0); |
0 | 370 if (!st) |
3486 | 371 return AVERROR(ENOMEM); |
0 | 372 st->id = get_be16(pb); |
373 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
|
374 st->codec->bit_rate = get_be32(pb); /* bit rate */ |
0 | 375 get_be32(pb); /* max packet size */ |
376 get_be32(pb); /* avg packet size */ | |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
85
diff
changeset
|
377 start_time = get_be32(pb); /* start time */ |
0 | 378 get_be32(pb); /* preroll */ |
188
6c9d6422a2f6
update duration and start_time - add av_new_stream() usage
bellard
parents:
85
diff
changeset
|
379 duration = get_be32(pb); /* duration */ |
743 | 380 st->start_time = start_time; |
381 st->duration = duration; | |
0 | 382 get_str8(pb, buf, sizeof(buf)); /* desc */ |
383 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
|
384 st->codec->codec_type = CODEC_TYPE_DATA; |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
385 st->priv_data = ff_rm_alloc_rmstream(); |
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
386 if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data, |
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
387 get_be32(pb)) < 0) |
2707
0199fcbb9d23
Split out the MDPR chunk reading into its own function.
benoit
parents:
2696
diff
changeset
|
388 return -1; |
0 | 389 break; |
390 case MKTAG('D', 'A', 'T', 'A'): | |
391 goto header_end; | |
392 default: | |
393 /* unknown tag: skip it */ | |
394 url_fskip(pb, tag_size - 10); | |
395 break; | |
396 } | |
397 } | |
398 header_end: | |
399 rm->nb_packets = get_be32(pb); /* number of packets */ | |
400 if (!rm->nb_packets && (flags & 4)) | |
401 rm->nb_packets = 3600 * 25; | |
402 get_be32(pb); /* next data header */ | |
403 return 0; | |
404 } | |
405 | |
406 static int get_num(ByteIOContext *pb, int *len) | |
407 { | |
408 int n, n1; | |
409 | |
410 n = get_be16(pb); | |
411 (*len)-=2; | |
2791
5d0fecceff17
Revert r10892, it's wrong and no longer needed to prevent crashes
rtogni
parents:
2771
diff
changeset
|
412 n &= 0x7FFF; |
0 | 413 if (n >= 0x4000) { |
414 return n - 0x4000; | |
415 } else { | |
416 n1 = get_be16(pb); | |
417 (*len)-=2; | |
418 return (n << 16) | n1; | |
419 } | |
420 } | |
421 | |
194 | 422 /* multiple of 20 bytes for ra144 (ugly) */ |
423 #define RAW_PACKET_SIZE 1000 | |
424 | |
613 | 425 static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){ |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
426 RMDemuxContext *rm = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
427 ByteIOContext *pb = s->pb; |
612 | 428 int len, num, res, i; |
429 AVStream *st; | |
632 | 430 uint32_t state=0xFFFFFFFF; |
612 | 431 |
432 while(!url_feof(pb)){ | |
3207 | 433 *pos= url_ftell(pb) - 3; |
612 | 434 if(rm->remaining_len > 0){ |
435 num= rm->current_stream; | |
436 len= rm->remaining_len; | |
437 *timestamp = AV_NOPTS_VALUE; | |
438 *flags= 0; | |
439 }else{ | |
632 | 440 state= (state<<8) + get_byte(pb); |
885 | 441 |
632 | 442 if(state == MKBETAG('I', 'N', 'D', 'X')){ |
4693
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
443 int n_pkts, expected_len; |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
444 len = get_be32(pb); |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
445 url_fskip(pb, 2); |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
446 n_pkts = get_be32(pb); |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
447 expected_len = 20 + n_pkts * 14; |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
448 if (len == 20) |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
449 /* some files don't add index entries to chunk size... */ |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
450 len = expected_len; |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
451 else if (len != expected_len) |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
452 av_log(s, AV_LOG_WARNING, |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
453 "Index size %d (%d pkts) is wrong, should be %d.\n", |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
454 len, n_pkts, expected_len); |
4de640349078
Correctly skip complete INDX chunks, i.e. read the 32-bit header correctly
rbultje
parents:
4692
diff
changeset
|
455 len -= 14; // we already read part of the index header |
632 | 456 if(len<0) |
457 continue; | |
458 goto skip; | |
459 } | |
885 | 460 |
632 | 461 if(state > (unsigned)0xFFFF || state < 12) |
612 | 462 continue; |
632 | 463 len=state; |
464 state= 0xFFFFFFFF; | |
465 | |
612 | 466 num = get_be16(pb); |
467 *timestamp = get_be32(pb); | |
468 res= get_byte(pb); /* reserved */ | |
469 *flags = get_byte(pb); /* flags */ | |
613 | 470 |
885 | 471 |
612 | 472 len -= 12; |
473 } | |
474 for(i=0;i<s->nb_streams;i++) { | |
475 st = s->streams[i]; | |
476 if (num == st->id) | |
477 break; | |
478 } | |
479 if (i == s->nb_streams) { | |
632 | 480 skip: |
612 | 481 /* skip packet if unknown number */ |
482 url_fskip(pb, len); | |
4692
71f1392ab8d4
Prevent (negative) overflow of rm->remaining_len. This evaluation really only
rbultje
parents:
4691
diff
changeset
|
483 rm->remaining_len = 0; |
612 | 484 continue; |
485 } | |
486 *stream_index= i; | |
885 | 487 |
612 | 488 return len; |
489 } | |
490 return -1; | |
491 } | |
492 | |
4036
1349c277efbd
Add ByteIOContext argument to public ff_rm_* functions so that we can
rbultje
parents:
4014
diff
changeset
|
493 static int rm_assemble_video_frame(AVFormatContext *s, ByteIOContext *pb, |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
494 RMDemuxContext *rm, RMStream *vst, |
4723
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
495 AVPacket *pkt, int len, int *pseq) |
2653 | 496 { |
497 int hdr, seq, pic_num, len2, pos; | |
498 int type; | |
499 | |
500 hdr = get_byte(pb); len--; | |
501 type = hdr >> 6; | |
4142 | 502 |
503 if(type != 3){ // not frame as a part of packet | |
2653 | 504 seq = get_byte(pb); len--; |
4142 | 505 } |
506 if(type != 1){ // not whole frame | |
2653 | 507 len2 = get_num(pb, &len); |
4142 | 508 pos = get_num(pb, &len); |
509 pic_num = get_byte(pb); len--; | |
510 } | |
511 if(len<0) | |
512 return -1; | |
513 rm->remaining_len = len; | |
514 if(type&1){ // frame, not slice | |
515 if(type == 3) // frame as a part of packet | |
516 len= len2; | |
517 if(rm->remaining_len < len) | |
4141
657498d1307e
Add a few error checks to rm_assemble_video_frame()
michael
parents:
4140
diff
changeset
|
518 return -1; |
4142 | 519 rm->remaining_len -= len; |
2653 | 520 if(av_new_packet(pkt, len + 9) < 0) |
521 return AVERROR(EIO); | |
522 pkt->data[0] = 0; | |
523 AV_WL32(pkt->data + 1, 1); | |
524 AV_WL32(pkt->data + 5, 0); | |
525 get_buffer(pb, pkt->data + 9, len); | |
526 return 0; | |
527 } | |
528 //now we have to deal with single slice | |
529 | |
4723
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
530 *pseq = seq; |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
531 if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
532 vst->slices = ((hdr & 0x3F) << 1) + 1; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
533 vst->videobufsize = len2 + 8*vst->slices + 1; |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
534 av_free_packet(&vst->pkt); //FIXME this should be output. |
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
535 if(av_new_packet(&vst->pkt, vst->videobufsize) < 0) |
2763 | 536 return AVERROR(ENOMEM); |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
537 vst->videobufpos = 8*vst->slices + 1; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
538 vst->cur_slice = 0; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
539 vst->curpic_num = pic_num; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
540 vst->pktpos = url_ftell(pb); |
2653 | 541 } |
2766 | 542 if(type == 2) |
2653 | 543 len = FFMIN(len, pos); |
544 | |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
545 if(++vst->cur_slice > vst->slices) |
2653 | 546 return 1; |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
547 AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1); |
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
548 AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
549 if(vst->videobufpos + len > vst->videobufsize) |
2653 | 550 return 1; |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
551 if (get_buffer(pb, vst->pkt.data + vst->videobufpos, len) != len) |
2653 | 552 return AVERROR(EIO); |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
553 vst->videobufpos += len; |
2653 | 554 rm->remaining_len-= len; |
555 | |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
556 if(type == 2 || (vst->videobufpos) == vst->videobufsize){ |
4145 | 557 vst->pkt.data[0] = vst->cur_slice-1; |
558 *pkt= vst->pkt; | |
4173 | 559 vst->pkt.data= NULL; |
4145 | 560 vst->pkt.size= 0; |
561 if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin | |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
562 memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices, |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
563 vst->videobufpos - 1 - 8*vst->slices); |
4146
af6cde9a76d1
10l set AVPacket.size to the true size of the returned data instead of
michael
parents:
4145
diff
changeset
|
564 pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices); |
4145 | 565 pkt->pts = AV_NOPTS_VALUE; |
566 pkt->pos = vst->pktpos; | |
567 return 0; | |
2653 | 568 } |
569 | |
570 return 1; | |
571 } | |
572 | |
2725 | 573 static inline void |
574 rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt) | |
575 { | |
576 uint8_t *ptr; | |
577 int j; | |
578 | |
579 if (st->codec->codec_id == CODEC_ID_AC3) { | |
580 ptr = pkt->data; | |
581 for (j=0;j<pkt->size;j+=2) { | |
582 FFSWAP(int, ptr[0], ptr[1]); | |
583 ptr += 2; | |
584 } | |
585 } | |
586 } | |
587 | |
2889 | 588 int |
4036
1349c277efbd
Add ByteIOContext argument to public ff_rm_* functions so that we can
rbultje
parents:
4014
diff
changeset
|
589 ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb, |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
590 AVStream *st, RMStream *ast, int len, AVPacket *pkt, |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
591 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
|
592 { |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
593 RMDemuxContext *rm = s->priv_data; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
594 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
595 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
|
596 rm->current_stream= st->id; |
4723
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
597 if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq)) |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
598 return -1; //got partial frame |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
599 } 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
|
600 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
|
601 (st->codec->codec_id == CODEC_ID_COOK) || |
3945 | 602 (st->codec->codec_id == CODEC_ID_ATRAC3) || |
603 (st->codec->codec_id == CODEC_ID_SIPR)) { | |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
604 int x; |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
605 int sps = ast->sub_packet_size; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
606 int cfs = ast->coded_framesize; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
607 int h = ast->sub_packet_h; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
608 int y = ast->sub_packet_cnt; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
609 int w = ast->audio_framesize; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
610 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
611 if (*flags & 2) |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
612 y = ast->sub_packet_cnt = 0; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
613 if (!y) |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
614 ast->audiotimestamp = *timestamp; |
2722
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 switch(st->codec->codec_id) { |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
617 case CODEC_ID_RA_288: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
618 for (x = 0; x < h/2; x++) |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
619 get_buffer(pb, ast->pkt.data+x*2*w+y*cfs, cfs); |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
620 break; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
621 case CODEC_ID_ATRAC3: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
622 case CODEC_ID_COOK: |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
623 for (x = 0; x < w/sps; x++) |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
624 get_buffer(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
625 break; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
626 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
627 |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
628 if (++(ast->sub_packet_cnt) < h) |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
629 return -1; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
630 else { |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
631 ast->sub_packet_cnt = 0; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
632 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
|
633 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
|
634 // Release first audio packet |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
635 av_new_packet(pkt, st->codec->block_align); |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
636 memcpy(pkt->data, ast->pkt.data, st->codec->block_align); //FIXME avoid this |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
637 *timestamp = ast->audiotimestamp; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
638 *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
|
639 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
640 } 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
|
641 int x; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
642 rm->audio_stream_num = st->index; |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
643 ast->sub_packet_cnt = (get_be16(pb) & 0xf0) >> 4; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
644 if (ast->sub_packet_cnt) { |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
645 for (x = 0; x < ast->sub_packet_cnt; x++) |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
646 ast->sub_packet_lengths[x] = get_be16(pb); |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
647 // Release first audio packet |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
648 rm->audio_pkt_cnt = ast->sub_packet_cnt - 1; |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
649 av_get_packet(pb, pkt, ast->sub_packet_lengths[0]); |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
650 *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
|
651 } |
2940 | 652 } else { |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
653 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
|
654 rm_ac3_swap_bytes(st, pkt); |
2940 | 655 } |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
656 } else |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
657 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
|
658 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
659 pkt->stream_index = st->index; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
660 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
661 #if 0 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
662 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
|
663 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
|
664 int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1); |
4511 | 665 av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq); |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
666 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
667 seq |= (*timestamp&~0x3FFF); |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
668 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
|
669 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
|
670 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
671 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
672 #endif |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
673 |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
674 pkt->pts= *timestamp; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
675 if (*flags & 2) |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
676 pkt->flags |= PKT_FLAG_KEY; |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
677 |
4096
233ba738a68e
Don't access RMContext directly in rdt.c. Rather, use the return value of
rbultje
parents:
4075
diff
changeset
|
678 return st->codec->codec_type == CODEC_TYPE_AUDIO ? rm->audio_pkt_cnt : 0; |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
679 } |
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
680 |
4135
fd0fc1e26d82
Add audio_pkt_cnt return value to ff_rm_retrieve_cache(). See discussion in
rbultje
parents:
4133
diff
changeset
|
681 int |
4036
1349c277efbd
Add ByteIOContext argument to public ff_rm_* functions so that we can
rbultje
parents:
4014
diff
changeset
|
682 ff_rm_retrieve_cache (AVFormatContext *s, ByteIOContext *pb, |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
683 AVStream *st, RMStream *ast, AVPacket *pkt) |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
684 { |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
685 RMDemuxContext *rm = s->priv_data; |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
686 |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
687 assert (rm->audio_pkt_cnt > 0); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
688 |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
689 if (st->codec->codec_id == CODEC_ID_AAC) |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
690 av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
691 else { |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
692 av_new_packet(pkt, st->codec->block_align); |
4144
4970ba98ca58
Replace buffer by AVPacket and avoid a memcpy() for video when the number
michael
parents:
4143
diff
changeset
|
693 memcpy(pkt->data, ast->pkt.data + st->codec->block_align * //FIXME avoid this |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
694 (ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt), |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
695 st->codec->block_align); |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
696 } |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
697 rm->audio_pkt_cnt--; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
698 pkt->flags = 0; |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
699 pkt->stream_index = st->index; |
4135
fd0fc1e26d82
Add audio_pkt_cnt return value to ff_rm_retrieve_cache(). See discussion in
rbultje
parents:
4133
diff
changeset
|
700 |
fd0fc1e26d82
Add audio_pkt_cnt return value to ff_rm_retrieve_cache(). See discussion in
rbultje
parents:
4133
diff
changeset
|
701 return rm->audio_pkt_cnt; |
2724
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
702 } |
1f752c3afdc8
Isolate caching of audio frames in its own function.
benoit
parents:
2723
diff
changeset
|
703 |
0 | 704 static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) |
705 { | |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
706 RMDemuxContext *rm = s->priv_data; |
4691 | 707 ByteIOContext *pb = s->pb; |
0 | 708 AVStream *st; |
4723
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
709 int i, len, res; |
613 | 710 int64_t timestamp, pos; |
4723
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
711 int old_flags, flags; |
0 | 712 |
888 | 713 if (rm->audio_pkt_cnt) { |
879 | 714 // If there are queued audio packet return them first |
715 st = s->streams[rm->audio_stream_num]; | |
4133
90a12fced519
Add RMStream object as function argument to public functions so that non-.rm
rbultje
parents:
4132
diff
changeset
|
716 ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt); |
888 | 717 } else if (rm->old_format) { |
4691 | 718 RMStream *ast; |
719 | |
720 st = s->streams[0]; | |
721 ast = st->priv_data; | |
722 if (st->codec->codec_id == CODEC_ID_RA_288) { | |
723 int x, y; | |
888 | 724 |
4691 | 725 for (y = 0; y < ast->sub_packet_h; y++) |
726 for (x = 0; x < ast->sub_packet_h/2; x++) | |
727 if (get_buffer(pb, ast->pkt.data+x*2*ast->audio_framesize+y*ast->coded_framesize, ast->coded_framesize) <= 0) | |
728 return AVERROR(EIO); | |
729 rm->audio_stream_num = 0; | |
730 rm->audio_pkt_cnt = ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - 1; | |
731 // Release first audio packet | |
732 av_new_packet(pkt, st->codec->block_align); | |
733 memcpy(pkt->data, ast->pkt.data, st->codec->block_align); //FIXME avoid this | |
734 pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe | |
735 pkt->stream_index = 0; | |
736 } else { | |
737 /* just read raw bytes */ | |
738 len = RAW_PACKET_SIZE; | |
739 len= av_get_packet(pb, pkt, len); | |
740 pkt->stream_index = 0; | |
741 if (len <= 0) { | |
742 return AVERROR(EIO); | |
743 } | |
744 pkt->size = len; | |
888 | 745 } |
4691 | 746 rm_ac3_swap_bytes(st, pkt); |
194 | 747 } else { |
4691 | 748 int seq=1; |
652 | 749 resync: |
613 | 750 len=sync(s, ×tamp, &flags, &i, &pos); |
612 | 751 if(len<0) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2237
diff
changeset
|
752 return AVERROR(EIO); |
612 | 753 st = s->streams[i]; |
754 | |
4723
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
755 old_flags = flags; |
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
756 res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt, |
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
757 &seq, &flags, ×tamp); |
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
758 if((old_flags&2) && (seq&0x7F) == 1) |
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
759 av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME); |
a2390c6a35e6
Fix index generation in the way that it was supposed to be used. See the
rbultje
parents:
4693
diff
changeset
|
760 if (res < 0) |
2722
65dcef6d93e1
Split out the packet parsing from the main function body in rmdec.c
benoit
parents:
2721
diff
changeset
|
761 goto resync; |
879 | 762 |
4686
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
763 if( (st->discard >= AVDISCARD_NONKEY && !(flags&2)) |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
764 || st->discard >= AVDISCARD_ALL){ |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
765 av_free_packet(pkt); |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
766 while (rm->audio_pkt_cnt > 0) { |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
767 ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt); |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
768 av_free_packet(pkt); |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
769 } |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
770 goto resync; |
83eb34995cfd
Move frame discarding out of the ff_rm_parse_packet() loop, and respect
rbultje
parents:
4523
diff
changeset
|
771 } |
0 | 772 } |
773 | |
774 return 0; | |
775 } | |
776 | |
777 static int rm_read_close(AVFormatContext *s) | |
778 { | |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
779 int i; |
879 | 780 |
4132
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
781 for (i=0;i<s->nb_streams;i++) |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
782 ff_rm_free_rmstream(s->streams[i]->priv_data); |
4c732153892b
Implement RMStream stream-specific private data object in the RM demuxer.
rbultje
parents:
4111
diff
changeset
|
783 |
0 | 784 return 0; |
785 } | |
786 | |
787 static int rm_probe(AVProbeData *p) | |
788 { | |
789 /* check file header */ | |
194 | 790 if ((p->buf[0] == '.' && p->buf[1] == 'R' && |
791 p->buf[2] == 'M' && p->buf[3] == 'F' && | |
792 p->buf[4] == 0 && p->buf[5] == 0) || | |
793 (p->buf[0] == '.' && p->buf[1] == 'r' && | |
794 p->buf[2] == 'a' && p->buf[3] == 0xfd)) | |
0 | 795 return AVPROBE_SCORE_MAX; |
796 else | |
797 return 0; | |
798 } | |
799 | |
885 | 800 static int64_t rm_read_dts(AVFormatContext *s, int stream_index, |
612 | 801 int64_t *ppos, int64_t pos_limit) |
802 { | |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
803 RMDemuxContext *rm = s->priv_data; |
612 | 804 int64_t pos, dts; |
613 | 805 int stream_index2, flags, len, h; |
612 | 806 |
807 pos = *ppos; | |
885 | 808 |
612 | 809 if(rm->old_format) |
810 return AV_NOPTS_VALUE; | |
811 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
812 url_fseek(s->pb, pos, SEEK_SET); |
612 | 813 rm->remaining_len=0; |
814 for(;;){ | |
613 | 815 int seq=1; |
816 AVStream *st; | |
817 | |
818 len=sync(s, &dts, &flags, &stream_index2, &pos); | |
612 | 819 if(len<0) |
820 return AV_NOPTS_VALUE; | |
613 | 821 |
822 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
|
823 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
824 h= get_byte(s->pb); len--; |
613 | 825 if(!(h & 0x40)){ |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
826 seq = get_byte(s->pb); len--; |
612 | 827 } |
828 } | |
885 | 829 |
613 | 830 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
|
831 // av_log(s, AV_LOG_DEBUG, "%d %d-%d %"PRId64" %d\n", flags, stream_index2, stream_index, dts, seq); |
979 | 832 av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME); |
613 | 833 if(stream_index2 == stream_index) |
834 break; | |
835 } | |
836 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2770
diff
changeset
|
837 url_fskip(s->pb, len); |
612 | 838 } |
839 *ppos = pos; | |
840 return dts; | |
841 } | |
842 | |
1169 | 843 AVInputFormat rm_demuxer = { |
0 | 844 "rm", |
4465 | 845 NULL_IF_CONFIG_SMALL("RealMedia format"), |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
846 sizeof(RMDemuxContext), |
0 | 847 rm_probe, |
848 rm_read_header, | |
849 rm_read_packet, | |
850 rm_read_close, | |
612 | 851 NULL, |
852 rm_read_dts, | |
0 | 853 }; |
3902
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
854 |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
855 AVInputFormat rdt_demuxer = { |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
856 "rdt", |
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
857 NULL_IF_CONFIG_SMALL("RDT demuxer"), |
4097
f8a743bd2df8
Split RMContext into RMDemux/MuxContext and make them private in rmdec/enc.c.
rbultje
parents:
4096
diff
changeset
|
858 sizeof(RMDemuxContext), |
4366 | 859 NULL, |
860 NULL, | |
861 NULL, | |
862 rm_read_close, | |
3902
5f9bec099c69
Add dynamic payload handlers to rdt.c. These follow the same API as the ones
rbultje
parents:
3874
diff
changeset
|
863 }; |