annotate rl2.c @ 6085:72c7c3d5c4e9 libavformat

matroskaenc: Mux clusters better Start them on keyframes when reasonable, and delay writing audio packets to help ensure that there's audio samples available for the first frame in clusters. Patch by James Zern <jzern at google>
author conrad
date Fri, 04 Jun 2010 22:40:50 +0000
parents 178de7695c6c
children 29171d6af13b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
1 /*
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
2 * RL2 Format Demuxer
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
3 * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
4 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
5 * This file is part of FFmpeg.
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
6 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
11 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
15 * Lesser General Public License for more details.
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
16 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
20 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
21
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
22 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
23 * RL2 file demuxer
5969
178de7695c6c Remove explicit filename from Doxygen @file commands.
diego
parents: 5910
diff changeset
24 * @file
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
25 * @author Sascha Sommer (saschasommer@freenet.de)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
26 * For more information regarding the RL2 file format, visit:
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
27 * http://wiki.multimedia.cx/index.php?title=RL2
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
28 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
29 * extradata:
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
30 * 2 byte le initial drawing offset within 320x200 viewport
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
31 * 4 byte le number of used colors
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
32 * 256 * 3 bytes rgb palette
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
33 * optional background_frame
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
34 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
35
4201
7d2f3f1b68d8 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 3908
diff changeset
36 #include "libavutil/intreadwrite.h"
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
37 #include "avformat.h"
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
38
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
39 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
40
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
41 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
42 #define RLV2_TAG MKBETAG('R', 'L', 'V', '2')
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
43 #define RLV3_TAG MKBETAG('R', 'L', 'V', '3')
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
44
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
45 typedef struct Rl2DemuxContext {
3365
19bd4caf27a9 consistency cosmetics: indices --> indexes
diego
parents: 3172
diff changeset
46 unsigned int index_pos[2]; ///< indexes in the sample tables
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
47 } Rl2DemuxContext;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
48
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
49
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
50 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
51 * check if the file is in rl2 format
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
52 * @param p probe buffer
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
53 * @return 0 when the probe buffer does not contain rl2 data, > 0 otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
54 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
55 static int rl2_probe(AVProbeData *p)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
56 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
57
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
58 if(AV_RB32(&p->buf[0]) != FORM_TAG)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
59 return 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
60
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
61 if(AV_RB32(&p->buf[8]) != RLV2_TAG &&
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
62 AV_RB32(&p->buf[8]) != RLV3_TAG)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
63 return 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
64
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
65 return AVPROBE_SCORE_MAX;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
66 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
67
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
68 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
69 * read rl2 header data and setup the avstreams
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
70 * @param s demuxer context
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
71 * @param ap format parameters
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
72 * @return 0 on success, AVERROR otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
73 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
74 static av_cold int rl2_read_header(AVFormatContext *s,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
75 AVFormatParameters *ap)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
76 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
77 ByteIOContext *pb = s->pb;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
78 AVStream *st;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
79 unsigned int frame_count;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
80 unsigned int audio_frame_counter = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
81 unsigned int video_frame_counter = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
82 unsigned int back_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
83 int data_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
84 unsigned short encoding_method;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
85 unsigned short sound_rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
86 unsigned short rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
87 unsigned short channels;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
88 unsigned short def_sound_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
89 unsigned int signature;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
90 unsigned int pts_den = 11025; /* video only case */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
91 unsigned int pts_num = 1103;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
92 unsigned int* chunk_offset = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
93 int* chunk_size = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
94 int* audio_size = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
95 int i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
96 int ret = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
97
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
98 url_fskip(pb,4); /* skip FORM tag */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
99 back_size = get_le32(pb); /** get size of the background frame */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
100 signature = get_be32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
101 data_size = get_be32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
102 frame_count = get_le32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
103
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
104 /* disallow back_sizes and frame_counts that may lead to overflows later */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
105 if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t))
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
106 return AVERROR_INVALIDDATA;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
107
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
108 encoding_method = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
109 sound_rate = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
110 rate = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
111 channels = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
112 def_sound_size = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
113
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
114 /** setup video stream */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
115 st = av_new_stream(s, 0);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
116 if(!st)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
117 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
118
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4464
diff changeset
119 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
120 st->codec->codec_id = CODEC_ID_RL2;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
121 st->codec->codec_tag = 0; /* no fourcc */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
122 st->codec->width = 320;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
123 st->codec->height = 200;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
124
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
125 /** allocate and fill extradata */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
126 st->codec->extradata_size = EXTRADATA1_SIZE;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
127
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
128 if(signature == RLV3_TAG && back_size > 0)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
129 st->codec->extradata_size += back_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
130
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
131 st->codec->extradata = av_mallocz(st->codec->extradata_size +
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
132 FF_INPUT_BUFFER_PADDING_SIZE);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
133 if(!st->codec->extradata)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
134 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
135
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
136 if(get_buffer(pb,st->codec->extradata,st->codec->extradata_size) !=
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
137 st->codec->extradata_size)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
138 return AVERROR(EIO);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
139
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
140 /** setup audio stream if present */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
141 if(sound_rate){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
142 pts_num = def_sound_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
143 pts_den = rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
144
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
145 st = av_new_stream(s, 0);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
146 if (!st)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
147 return AVERROR(ENOMEM);
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4464
diff changeset
148 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
149 st->codec->codec_id = CODEC_ID_PCM_U8;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
150 st->codec->codec_tag = 1;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
151 st->codec->channels = channels;
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
152 st->codec->bits_per_coded_sample = 8;
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
153 st->codec->sample_rate = rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
154 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
155 st->codec->bits_per_coded_sample;
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
156 st->codec->block_align = st->codec->channels *
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
157 st->codec->bits_per_coded_sample / 8;
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
158 av_set_pts_info(st,32,1,rate);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
159 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
160
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
161 av_set_pts_info(s->streams[0], 32, pts_num, pts_den);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
162
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
163 chunk_size = av_malloc(frame_count * sizeof(uint32_t));
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
164 audio_size = av_malloc(frame_count * sizeof(uint32_t));
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
165 chunk_offset = av_malloc(frame_count * sizeof(uint32_t));
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
166
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
167 if(!chunk_size || !audio_size || !chunk_offset){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
168 av_free(chunk_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
169 av_free(audio_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
170 av_free(chunk_offset);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
171 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
172 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
173
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
174 /** read offset and size tables */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
175 for(i=0; i < frame_count;i++)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
176 chunk_size[i] = get_le32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
177 for(i=0; i < frame_count;i++)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
178 chunk_offset[i] = get_le32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
179 for(i=0; i < frame_count;i++)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
180 audio_size[i] = get_le32(pb) & 0xFFFF;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
181
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
182 /** build the sample index */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
183 for(i=0;i<frame_count;i++){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
184 if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
185 ret = AVERROR_INVALIDDATA;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
186 break;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
187 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
188
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
189 if(sound_rate && audio_size[i]){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
190 av_add_index_entry(s->streams[1], chunk_offset[i],
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
191 audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
192 audio_frame_counter += audio_size[i] / channels;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
193 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
194 av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i],
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
195 video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
196 ++video_frame_counter;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
197 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
198
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
199
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
200 av_free(chunk_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
201 av_free(audio_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
202 av_free(chunk_offset);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
203
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
204 return ret;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
205 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
206
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
207 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
208 * read a single audio or video packet
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
209 * @param s demuxer context
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
210 * @param pkt the packet to be filled
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
211 * @return 0 on success, AVERROR otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
212 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
213 static int rl2_read_packet(AVFormatContext *s,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
214 AVPacket *pkt)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
215 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
216 Rl2DemuxContext *rl2 = s->priv_data;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
217 ByteIOContext *pb = s->pb;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
218 AVIndexEntry *sample = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
219 int i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
220 int ret = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
221 int stream_id = -1;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
222 int64_t pos = INT64_MAX;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
223
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
224 /** check if there is a valid video or audio entry that can be used */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
225 for(i=0; i<s->nb_streams; i++){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
226 if(rl2->index_pos[i] < s->streams[i]->nb_index_entries
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
227 && s->streams[i]->index_entries[ rl2->index_pos[i] ].pos < pos){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
228 sample = &s->streams[i]->index_entries[ rl2->index_pos[i] ];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
229 pos= sample->pos;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
230 stream_id= i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
231 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
232 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
233
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
234 if(stream_id == -1)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
235 return AVERROR(EIO);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
236
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
237 ++rl2->index_pos[stream_id];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
238
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
239 /** position the stream (will probably be there anyway) */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
240 url_fseek(pb, sample->pos, SEEK_SET);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
241
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
242 /** fill the packet */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
243 ret = av_get_packet(pb, pkt, sample->size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
244 if(ret != sample->size){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
245 av_free_packet(pkt);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
246 return AVERROR(EIO);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
247 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
248
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
249 pkt->stream_index = stream_id;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
250 pkt->pts = sample->timestamp;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
251
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
252 return ret;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
253 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
254
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
255 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
256 * seek to a new timestamp
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
257 * @param s demuxer context
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
258 * @param stream_index index of the stream that should be seeked
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
259 * @param timestamp wanted timestamp
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
260 * @param flags direction and seeking mode
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
261 * @return 0 on success, -1 otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
262 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
263 static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
264 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
265 AVStream *st = s->streams[stream_index];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
266 Rl2DemuxContext *rl2 = s->priv_data;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
267 int i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
268 int index = av_index_search_timestamp(st, timestamp, flags);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
269 if(index < 0)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
270 return -1;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
271
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
272 rl2->index_pos[stream_index] = index;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
273 timestamp = st->index_entries[index].timestamp;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
274
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
275 for(i=0; i < s->nb_streams; i++){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
276 AVStream *st2 = s->streams[i];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
277 index = av_index_search_timestamp(st2,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
278 av_rescale_q(timestamp, st->time_base, st2->time_base),
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
279 flags | AVSEEK_FLAG_BACKWARD);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
280
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
281 if(index < 0)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
282 index = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
283
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
284 rl2->index_pos[i] = index;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
285 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
286
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
287 return 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
288 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
289
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
290 AVInputFormat rl2_demuxer = {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
291 "rl2",
4464
6b79937e78ae cosmetics: format long_name spelling fixes
diego
parents: 4331
diff changeset
292 NULL_IF_CONFIG_SMALL("RL2 format"),
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
293 sizeof(Rl2DemuxContext),
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
294 rl2_probe,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
295 rl2_read_header,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
296 rl2_read_packet,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
297 NULL,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
298 rl2_read_seek,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
299 };
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
300