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