annotate ffm.c @ 318:54e915169d48 libavformat

Add more resilience in reading ffm files. In particular, don't assume that the write pointer is correct. This can happen in certain failure modes.
author philipjsg
date Wed, 19 Nov 2003 02:34:40 +0000
parents a313e1080322
children 3a40642dc4df
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
1 /*
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
2 * FFM (ffserver live feed) encoder and decoder
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
3 * Copyright (c) 2001 Fabrice Bellard.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
4 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
9 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
13 * Lesser General Public License for more details.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
14 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
18 */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
19 #include "avformat.h"
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
20 #include <unistd.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
21
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
22 /* The FFM file is made of blocks of fixed size */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
23 #define FFM_HEADER_SIZE 14
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
24 #define PACKET_ID 0x666d
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
25
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
26 /* each packet contains frames (which can span several packets */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
27 #define FRAME_HEADER_SIZE 8
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
28 #define FLAG_KEY_FRAME 0x01
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
29
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
30 typedef struct FFMStream {
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
31 int64_t pts;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
32 } FFMStream;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
33
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
34 enum {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
35 READ_HEADER,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
36 READ_DATA,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
37 };
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
38
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
39 typedef struct FFMContext {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
40 /* only reading mode */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
41 offset_t write_index, file_size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
42 int read_state;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
43 uint8_t header[FRAME_HEADER_SIZE];
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
44
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
45 /* read and write */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
46 int first_packet; /* true if first packet, needed to set the discontinuity tag */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
47 int packet_size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
48 int frame_offset;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
49 int64_t pts;
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
50 uint8_t *packet_ptr, *packet_end;
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
51 uint8_t packet[FFM_PACKET_SIZE];
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
52 } FFMContext;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
53
318
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
54 static int64_t get_pts(AVFormatContext *s, offset_t pos);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
55
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
56 /* disable pts hack for testing */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
57 int ffm_nopts = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
58
277
a313e1080322 disable encoders where appropriate (patch courtesy of BERO
melanson
parents: 241
diff changeset
59 #ifdef CONFIG_ENCODERS
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
60 static void flush_packet(AVFormatContext *s)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
61 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
62 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
63 int fill_size, h;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
64 ByteIOContext *pb = &s->pb;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
65
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
66 fill_size = ffm->packet_end - ffm->packet_ptr;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
67 memset(ffm->packet_ptr, 0, fill_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
68
318
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
69 if (url_ftell(pb) % ffm->packet_size)
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
70 av_abort();
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
71
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
72 /* put header */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
73 put_be16(pb, PACKET_ID);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
74 put_be16(pb, fill_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
75 put_be64(pb, ffm->pts);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
76 h = ffm->frame_offset;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
77 if (ffm->first_packet)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
78 h |= 0x8000;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
79 put_be16(pb, h);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
80 put_buffer(pb, ffm->packet, ffm->packet_end - ffm->packet);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
81
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
82 /* prepare next packet */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
83 ffm->frame_offset = 0; /* no key frame */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
84 ffm->pts = 0; /* no pts */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
85 ffm->packet_ptr = ffm->packet;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
86 ffm->first_packet = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
87 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
88
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
89 /* 'first' is true if first data of a frame */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
90 static void ffm_write_data(AVFormatContext *s,
241
3d92f793fd67 64 bit pts for writing - more const usage
bellard
parents: 187
diff changeset
91 const uint8_t *buf, int size,
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
92 int64_t pts, int first)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
93 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
94 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
95 int len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
96
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
97 if (first && ffm->frame_offset == 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
98 ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
99 if (first && ffm->pts == 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
100 ffm->pts = pts;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
101
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
102 /* write as many packets as needed */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
103 while (size > 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
104 len = ffm->packet_end - ffm->packet_ptr;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
105 if (len > size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
106 len = size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
107 memcpy(ffm->packet_ptr, buf, len);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
108
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
109 ffm->packet_ptr += len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
110 buf += len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
111 size -= len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
112 if (ffm->packet_ptr >= ffm->packet_end) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
113 /* special case : no pts in packet : we leave the current one */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
114 if (ffm->pts == 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
115 ffm->pts = pts;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
116
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
117 flush_packet(s);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
118 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
119 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
120 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
121
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
122 static int ffm_write_header(AVFormatContext *s)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
123 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
124 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
125 AVStream *st;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
126 FFMStream *fst;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
127 ByteIOContext *pb = &s->pb;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
128 AVCodecContext *codec;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
129 int bit_rate, i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
130
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
131 ffm->packet_size = FFM_PACKET_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
132
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
133 /* header */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
134 put_tag(pb, "FFM1");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
135 put_be32(pb, ffm->packet_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
136 /* XXX: store write position in other file ? */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
137 put_be64(pb, ffm->packet_size); /* current write position */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
138
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
139 put_be32(pb, s->nb_streams);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
140 bit_rate = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
141 for(i=0;i<s->nb_streams;i++) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
142 st = s->streams[i];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
143 bit_rate += st->codec.bit_rate;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
144 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
145 put_be32(pb, bit_rate);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
146
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
147 /* list of streams */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
148 for(i=0;i<s->nb_streams;i++) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
149 st = s->streams[i];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
150 fst = av_mallocz(sizeof(FFMStream));
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
151 if (!fst)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
152 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
153 st->priv_data = fst;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
154
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
155 codec = &st->codec;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
156 /* generic info */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
157 put_be32(pb, codec->codec_id);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
158 put_byte(pb, codec->codec_type);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
159 put_be32(pb, codec->bit_rate);
5
39c4c4336486 cleanup
michaelni
parents: 0
diff changeset
160 put_be32(pb, st->quality);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
161 put_be32(pb, codec->flags);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
162 /* specific info */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
163 switch(codec->codec_type) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
164 case CODEC_TYPE_VIDEO:
85
25062c9b1f86 per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents: 79
diff changeset
165 put_be32(pb, codec->frame_rate_base);
25062c9b1f86 per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents: 79
diff changeset
166 put_be32(pb, codec->frame_rate);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
167 put_be16(pb, codec->width);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
168 put_be16(pb, codec->height);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
169 put_be16(pb, codec->gop_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
170 put_byte(pb, codec->qmin);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
171 put_byte(pb, codec->qmax);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
172 put_byte(pb, codec->max_qdiff);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
173 put_be16(pb, (int) (codec->qcompress * 10000.0));
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
174 put_be16(pb, (int) (codec->qblur * 10000.0));
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
175 put_be32(pb, codec->bit_rate_tolerance);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
176 put_strz(pb, codec->rc_eq);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
177 put_be32(pb, codec->rc_max_rate);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
178 put_be32(pb, codec->rc_min_rate);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
179 put_be32(pb, codec->rc_buffer_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
180 put_be64_double(pb, codec->i_quant_factor);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
181 put_be64_double(pb, codec->b_quant_factor);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
182 put_be64_double(pb, codec->i_quant_offset);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
183 put_be64_double(pb, codec->b_quant_offset);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
184 put_be32(pb, codec->dct_algo);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
185 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
186 case CODEC_TYPE_AUDIO:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
187 put_be32(pb, codec->sample_rate);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
188 put_le16(pb, codec->channels);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
189 put_le16(pb, codec->frame_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
190 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
191 default:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
192 av_abort();
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
193 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
194 /* hack to have real time */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
195 if (ffm_nopts)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
196 fst->pts = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
197 else
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
198 fst->pts = av_gettime();
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
199 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
200
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
201 /* flush until end of block reached */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
202 while ((url_ftell(pb) % ffm->packet_size) != 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
203 put_byte(pb, 0);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
204
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
205 put_flush_packet(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
206
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
207 /* init packet mux */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
208 ffm->packet_ptr = ffm->packet;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
209 ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE;
318
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
210 if (ffm->packet_end < ffm->packet)
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
211 av_abort();
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
212 ffm->frame_offset = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
213 ffm->pts = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
214 ffm->first_packet = 1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
215
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
216 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
217 fail:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
218 for(i=0;i<s->nb_streams;i++) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
219 st = s->streams[i];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
220 av_freep(&st->priv_data);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
221 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
222 return -1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
223 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
224
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
225 static int ffm_write_packet(AVFormatContext *s, int stream_index,
241
3d92f793fd67 64 bit pts for writing - more const usage
bellard
parents: 187
diff changeset
226 const uint8_t *buf, int size, int64_t force_pts)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
227 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
228 AVStream *st = s->streams[stream_index];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
229 FFMStream *fst = st->priv_data;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
230 int64_t pts;
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
231 uint8_t header[FRAME_HEADER_SIZE];
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
232 int duration;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
233
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
234 if (st->codec.codec_type == CODEC_TYPE_AUDIO) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
235 duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
236 } else {
85
25062c9b1f86 per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents: 79
diff changeset
237 duration = (1000000.0 * st->codec.frame_rate_base / (float)st->codec.frame_rate);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
238 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
239
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
240 pts = fst->pts;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
241 /* packet size & key_frame */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
242 header[0] = stream_index;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
243 header[1] = 0;
7
47e502ac6349 AVVideoFrame -> AVFrame
michaelni
parents: 6
diff changeset
244 if (st->codec.coded_frame->key_frame) //if st->codec.coded_frame==NULL then there is a bug somewhere else
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
245 header[1] |= FLAG_KEY_FRAME;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
246 header[2] = (size >> 16) & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
247 header[3] = (size >> 8) & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
248 header[4] = size & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
249 header[5] = (duration >> 16) & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
250 header[6] = (duration >> 8) & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
251 header[7] = duration & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
252 ffm_write_data(s, header, FRAME_HEADER_SIZE, pts, 1);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
253 ffm_write_data(s, buf, size, pts, 0);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
254
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
255 fst->pts += duration;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
256 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
257 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
258
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
259 static int ffm_write_trailer(AVFormatContext *s)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
260 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
261 ByteIOContext *pb = &s->pb;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
262 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
263 int i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
264
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
265 /* flush packets */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
266 if (ffm->packet_ptr > ffm->packet)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
267 flush_packet(s);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
268
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
269 put_flush_packet(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
270
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
271 if (!url_is_streamed(pb)) {
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
272 int64_t size;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
273 /* update the write offset */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
274 size = url_ftell(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
275 url_fseek(pb, 8, SEEK_SET);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
276 put_be64(pb, size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
277 put_flush_packet(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
278 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
279
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
280 for(i=0;i<s->nb_streams;i++)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
281 av_freep(&s->streams[i]->priv_data);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
282 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
283 }
277
a313e1080322 disable encoders where appropriate (patch courtesy of BERO
melanson
parents: 241
diff changeset
284 #endif //CONFIG_ENCODERS
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
285
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
286 /* ffm demux */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
287
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
288 static int ffm_is_avail_data(AVFormatContext *s, int size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
289 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
290 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
291 offset_t pos, avail_size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
292 int len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
293
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
294 len = ffm->packet_end - ffm->packet_ptr;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
295 if (!ffm_nopts) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
296 /* XXX: I don't understand this test, so I disabled it for testing */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
297 if (size <= len)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
298 return 1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
299 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
300 pos = url_ftell(&s->pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
301 if (pos == ffm->write_index) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
302 /* exactly at the end of stream */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
303 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
304 } else if (pos < ffm->write_index) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
305 avail_size = ffm->write_index - pos;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
306 } else {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
307 avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
308 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
309 avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
310 if (size <= avail_size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
311 return 1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
312 else
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
313 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
314 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
315
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
316 /* first is true if we read the frame header */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
317 static int ffm_read_data(AVFormatContext *s,
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
318 uint8_t *buf, int size, int first)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
319 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
320 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
321 ByteIOContext *pb = &s->pb;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
322 int len, fill_size, size1, frame_offset;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
323
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
324 size1 = size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
325 while (size > 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
326 redo:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
327 len = ffm->packet_end - ffm->packet_ptr;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
328 if (len > size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
329 len = size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
330 if (len == 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
331 if (url_ftell(pb) == ffm->file_size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
332 url_fseek(pb, ffm->packet_size, SEEK_SET);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
333 retry_read:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
334 get_be16(pb); /* PACKET_ID */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
335 fill_size = get_be16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
336 ffm->pts = get_be64(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
337 frame_offset = get_be16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
338 get_buffer(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
339 ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);
318
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
340 if (ffm->packet_end < ffm->packet)
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
341 av_abort();
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
342 /* if first packet or resynchronization packet, we must
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
343 handle it specifically */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
344 if (ffm->first_packet || (frame_offset & 0x8000)) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
345 if (!frame_offset) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
346 /* This packet has no frame headers in it */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
347 if (url_ftell(pb) >= ffm->packet_size * 3) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
348 url_fseek(pb, -ffm->packet_size * 2, SEEK_CUR);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
349 goto retry_read;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
350 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
351 /* This is bad, we cannot find a valid frame header */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
352 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
353 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
354 ffm->first_packet = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
355 if ((frame_offset & 0x7ffff) < FFM_HEADER_SIZE)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
356 av_abort();
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
357 ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
358 if (!first)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
359 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
360 } else {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
361 ffm->packet_ptr = ffm->packet;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
362 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
363 goto redo;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
364 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
365 memcpy(buf, ffm->packet_ptr, len);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
366 buf += len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
367 ffm->packet_ptr += len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
368 size -= len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
369 first = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
370 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
371 return size1 - size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
372 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
373
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
374
318
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
375 static void adjust_write_index(AVFormatContext *s)
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
376 {
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
377 FFMContext *ffm = s->priv_data;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
378 ByteIOContext *pb = &s->pb;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
379 int64_t pts;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
380 //offset_t orig_write_index = ffm->write_index;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
381 offset_t pos_min, pos_max;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
382 int64_t pts_start;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
383 offset_t ptr = url_ftell(pb);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
384
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
385
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
386 pos_min = 0;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
387 pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
388
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
389 pts_start = get_pts(s, pos_min);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
390
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
391 pts = get_pts(s, pos_max);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
392
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
393 if (pts - 100000 > pts_start)
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
394 return;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
395
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
396 ffm->write_index = FFM_PACKET_SIZE;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
397
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
398 pts_start = get_pts(s, pos_min);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
399
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
400 pts = get_pts(s, pos_max);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
401
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
402 if (pts - 100000 <= pts_start) {
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
403 while (1) {
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
404 offset_t newpos;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
405 int64_t newpts;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
406
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
407 newpos = ((pos_max + pos_min) / (2 * FFM_PACKET_SIZE)) * FFM_PACKET_SIZE;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
408
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
409 if (newpos == pos_min)
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
410 break;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
411
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
412 newpts = get_pts(s, newpos);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
413
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
414 if (newpts - 100000 <= pts) {
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
415 pos_max = newpos;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
416 pts = newpts;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
417 } else {
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
418 pos_min = newpos;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
419 }
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
420 }
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
421 ffm->write_index += pos_max;
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
422 }
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
423
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
424 //printf("Adjusted write index from %lld to %lld: pts=%0.6f\n", orig_write_index, ffm->write_index, pts / 1000000.);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
425 //printf("pts range %0.6f - %0.6f\n", get_pts(s, 0) / 1000000. , get_pts(s, ffm->file_size - 2 * FFM_PACKET_SIZE) / 1000000. );
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
426
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
427 url_fseek(pb, ptr, SEEK_SET);
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
428 }
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
429
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
430
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
431 static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
432 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
433 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
434 AVStream *st;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
435 FFMStream *fst;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
436 ByteIOContext *pb = &s->pb;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
437 AVCodecContext *codec;
187
2fa5e94ba716 add av_new_stream() usage
bellard
parents: 85
diff changeset
438 int i, nb_streams;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
439 uint32_t tag;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
440
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
441 /* header */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
442 tag = get_le32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
443 if (tag != MKTAG('F', 'F', 'M', '1'))
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
444 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
445 ffm->packet_size = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
446 if (ffm->packet_size != FFM_PACKET_SIZE)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
447 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
448 ffm->write_index = get_be64(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
449 /* get also filesize */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
450 if (!url_is_streamed(pb)) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
451 ffm->file_size = url_filesize(url_fileno(pb));
318
54e915169d48 Add more resilience in reading ffm files. In particular, don't assume
philipjsg
parents: 277
diff changeset
452 adjust_write_index(s);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
453 } else {
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
454 ffm->file_size = (uint64_t_C(1) << 63) - 1;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
455 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
456
187
2fa5e94ba716 add av_new_stream() usage
bellard
parents: 85
diff changeset
457 nb_streams = get_be32(pb);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
458 get_be32(pb); /* total bitrate */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
459 /* read each stream */
187
2fa5e94ba716 add av_new_stream() usage
bellard
parents: 85
diff changeset
460 for(i=0;i<nb_streams;i++) {
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
461 char rc_eq_buf[128];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
462
187
2fa5e94ba716 add av_new_stream() usage
bellard
parents: 85
diff changeset
463 st = av_new_stream(s, 0);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
464 if (!st)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
465 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
466 fst = av_mallocz(sizeof(FFMStream));
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
467 if (!fst)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
468 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
469 st->priv_data = fst;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
470
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
471 codec = &st->codec;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
472 /* generic info */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
473 st->codec.codec_id = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
474 st->codec.codec_type = get_byte(pb); /* codec_type */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
475 codec->bit_rate = get_be32(pb);
5
39c4c4336486 cleanup
michaelni
parents: 0
diff changeset
476 st->quality = get_be32(pb);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
477 codec->flags = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
478 /* specific info */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
479 switch(codec->codec_type) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
480 case CODEC_TYPE_VIDEO:
85
25062c9b1f86 per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents: 79
diff changeset
481 codec->frame_rate_base = get_be32(pb);
25062c9b1f86 per context frame_rate_base, this should finally fix frame_rate related av sync issues
michaelni
parents: 79
diff changeset
482 codec->frame_rate = get_be32(pb);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
483 codec->width = get_be16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
484 codec->height = get_be16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
485 codec->gop_size = get_be16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
486 codec->qmin = get_byte(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
487 codec->qmax = get_byte(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
488 codec->max_qdiff = get_byte(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
489 codec->qcompress = get_be16(pb) / 10000.0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
490 codec->qblur = get_be16(pb) / 10000.0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
491 codec->bit_rate_tolerance = get_be32(pb);
34
f17e285df237 use av_strdup()
bellard
parents: 7
diff changeset
492 codec->rc_eq = av_strdup(get_strz(pb, rc_eq_buf, sizeof(rc_eq_buf)));
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
493 codec->rc_max_rate = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
494 codec->rc_min_rate = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
495 codec->rc_buffer_size = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
496 codec->i_quant_factor = get_be64_double(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
497 codec->b_quant_factor = get_be64_double(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
498 codec->i_quant_offset = get_be64_double(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
499 codec->b_quant_offset = get_be64_double(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
500 codec->dct_algo = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
501 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
502 case CODEC_TYPE_AUDIO:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
503 codec->sample_rate = get_be32(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
504 codec->channels = get_le16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
505 codec->frame_size = get_le16(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
506 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
507 default:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
508 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
509 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
510
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
511 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
512
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
513 /* get until end of block reached */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
514 while ((url_ftell(pb) % ffm->packet_size) != 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
515 get_byte(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
516
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
517 /* init packet demux */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
518 ffm->packet_ptr = ffm->packet;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
519 ffm->packet_end = ffm->packet;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
520 ffm->frame_offset = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
521 ffm->pts = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
522 ffm->read_state = READ_HEADER;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
523 ffm->first_packet = 1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
524 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
525 fail:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
526 for(i=0;i<s->nb_streams;i++) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
527 st = s->streams[i];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
528 if (st) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
529 av_freep(&st->priv_data);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
530 av_free(st);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
531 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
532 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
533 return -1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
534 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
535
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
536 /* return < 0 if eof */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
537 static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
538 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
539 int size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
540 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
541 int duration;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
542
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
543 switch(ffm->read_state) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
544 case READ_HEADER:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
545 if (!ffm_is_avail_data(s, FRAME_HEADER_SIZE)) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
546 return -EAGAIN;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
547 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
548 #if 0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
549 printf("pos=%08Lx spos=%Lx, write_index=%Lx size=%Lx\n",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
550 url_ftell(&s->pb), s->pb.pos, ffm->write_index, ffm->file_size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
551 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
552 if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) !=
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
553 FRAME_HEADER_SIZE)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
554 return -EAGAIN;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
555 #if 0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
556 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
557 int i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
558 for(i=0;i<FRAME_HEADER_SIZE;i++)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
559 printf("%02x ", ffm->header[i]);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
560 printf("\n");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
561 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
562 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
563 ffm->read_state = READ_DATA;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
564 /* fall thru */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
565 case READ_DATA:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
566 size = (ffm->header[2] << 16) | (ffm->header[3] << 8) | ffm->header[4];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
567 if (!ffm_is_avail_data(s, size)) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
568 return -EAGAIN;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
569 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
570
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
571 duration = (ffm->header[5] << 16) | (ffm->header[6] << 8) | ffm->header[7];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
572
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
573 av_new_packet(pkt, size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
574 pkt->stream_index = ffm->header[0];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
575 if (ffm->header[1] & FLAG_KEY_FRAME)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
576 pkt->flags |= PKT_FLAG_KEY;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
577
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
578 ffm->read_state = READ_HEADER;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
579 if (ffm_read_data(s, pkt->data, size, 0) != size) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
580 /* bad case: desynchronized packet. we cancel all the packet loading */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
581 av_free_packet(pkt);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
582 return -EAGAIN;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
583 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
584 pkt->pts = ffm->pts;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
585 pkt->duration = duration;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
586 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
587 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
588 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
589 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
590
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
591 //#define DEBUG_SEEK
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
592
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
593 /* pos is between 0 and file_size - FFM_PACKET_SIZE. It is translated
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
594 by the write position inside this function */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
595 static void ffm_seek1(AVFormatContext *s, offset_t pos1)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
596 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
597 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
598 ByteIOContext *pb = &s->pb;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
599 offset_t pos;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
600
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
601 pos = pos1 + ffm->write_index;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
602 if (pos >= ffm->file_size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
603 pos -= (ffm->file_size - FFM_PACKET_SIZE);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
604 #ifdef DEBUG_SEEK
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
605 printf("seek to %Lx -> %Lx\n", pos1, pos);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
606 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
607 url_fseek(pb, pos, SEEK_SET);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
608 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
609
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
610 static int64_t get_pts(AVFormatContext *s, offset_t pos)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
611 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
612 ByteIOContext *pb = &s->pb;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
613 int64_t pts;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
614
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
615 ffm_seek1(s, pos);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
616 url_fskip(pb, 4);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
617 pts = get_be64(pb);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
618 #ifdef DEBUG_SEEK
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
619 printf("pts=%0.6f\n", pts / 1000000.0);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
620 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
621 return pts;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
622 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
623
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
624 /* seek to a given time in the file. The file read pointer is
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
625 positionned at or before pts. XXX: the following code is quite
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
626 approximative */
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
627 static int ffm_seek(AVFormatContext *s, int64_t wanted_pts)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
628 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
629 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
630 offset_t pos_min, pos_max, pos;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
631 int64_t pts_min, pts_max, pts;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
632 double pos1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
633
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
634 #ifdef DEBUG_SEEK
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
635 printf("wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
636 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
637 /* find the position using linear interpolation (better than
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
638 dichotomy in typical cases) */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
639 pos_min = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
640 pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
641 while (pos_min <= pos_max) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
642 pts_min = get_pts(s, pos_min);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
643 pts_max = get_pts(s, pos_max);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
644 /* linear interpolation */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
645 pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
646 (double)(pts_max - pts_min);
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
647 pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
648 if (pos <= pos_min)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
649 pos = pos_min;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
650 else if (pos >= pos_max)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
651 pos = pos_max;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
652 pts = get_pts(s, pos);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
653 /* check if we are lucky */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
654 if (pts == wanted_pts) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
655 goto found;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
656 } else if (pts > wanted_pts) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
657 pos_max = pos - FFM_PACKET_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
658 } else {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
659 pos_min = pos + FFM_PACKET_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
660 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
661 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
662 pos = pos_min;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
663 if (pos > 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
664 pos -= FFM_PACKET_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
665 found:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
666 ffm_seek1(s, pos);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
667 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
668 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
669
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
670 offset_t ffm_read_write_index(int fd)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
671 {
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
672 uint8_t buf[8];
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
673 offset_t pos;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
674 int i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
675
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
676 lseek(fd, 8, SEEK_SET);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
677 read(fd, buf, 8);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
678 pos = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
679 for(i=0;i<8;i++)
187
2fa5e94ba716 add av_new_stream() usage
bellard
parents: 85
diff changeset
680 pos |= (int64_t)buf[i] << (56 - i * 8);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
681 return pos;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
682 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
683
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
684 void ffm_write_write_index(int fd, offset_t pos)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
685 {
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 34
diff changeset
686 uint8_t buf[8];
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
687 int i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
688
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
689 for(i=0;i<8;i++)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
690 buf[i] = (pos >> (56 - i * 8)) & 0xff;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
691 lseek(fd, 8, SEEK_SET);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
692 write(fd, buf, 8);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
693 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
694
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
695 void ffm_set_write_index(AVFormatContext *s, offset_t pos, offset_t file_size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
696 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
697 FFMContext *ffm = s->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
698 ffm->write_index = pos;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
699 ffm->file_size = file_size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
700 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
701
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
702 static int ffm_read_close(AVFormatContext *s)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
703 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
704 AVStream *st;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
705 int i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
706
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
707 for(i=0;i<s->nb_streams;i++) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
708 st = s->streams[i];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
709 av_freep(&st->priv_data);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
710 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
711 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
712 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
713
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
714 static int ffm_probe(AVProbeData *p)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
715 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
716 if (p->buf_size >= 4 &&
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
717 p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' &&
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
718 p->buf[3] == '1')
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
719 return AVPROBE_SCORE_MAX + 1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
720 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
721 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
722
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
723 static AVInputFormat ffm_iformat = {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
724 "ffm",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
725 "ffm format",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
726 sizeof(FFMContext),
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
727 ffm_probe,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
728 ffm_read_header,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
729 ffm_read_packet,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
730 ffm_read_close,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
731 ffm_seek,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
732 };
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
733
277
a313e1080322 disable encoders where appropriate (patch courtesy of BERO
melanson
parents: 241
diff changeset
734 #ifdef CONFIG_ENCODERS
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
735 static AVOutputFormat ffm_oformat = {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
736 "ffm",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
737 "ffm format",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
738 "",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
739 "ffm",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
740 sizeof(FFMContext),
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
741 /* not really used */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
742 CODEC_ID_MP2,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
743 CODEC_ID_MPEG1VIDEO,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
744 ffm_write_header,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
745 ffm_write_packet,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
746 ffm_write_trailer,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
747 };
277
a313e1080322 disable encoders where appropriate (patch courtesy of BERO
melanson
parents: 241
diff changeset
748 #endif //CONFIG_ENCODERS
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
749
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
750 int ffm_init(void)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
751 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
752 av_register_input_format(&ffm_iformat);
277
a313e1080322 disable encoders where appropriate (patch courtesy of BERO
melanson
parents: 241
diff changeset
753 #ifdef CONFIG_ENCODERS
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
754 av_register_output_format(&ffm_oformat);
277
a313e1080322 disable encoders where appropriate (patch courtesy of BERO
melanson
parents: 241
diff changeset
755 #endif //CONFIG_ENCODERS
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
756 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
757 }