1 /*
2 * FFM (ffserver live feed) demuxer
3 * Copyright (c) 2001 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <stdint.h>
23
33
35 {
37 int64_t pos, avail_size;
39
41 if (size <= len)
42 return 1;
48 } else {
50 /* exactly at the end of stream */
54 } else {
56 }
57 }
59 if (size <= avail_size)
60 return 1;
61 else
63 }
64
66 {
71 return -1;
72 }
74 }
75 return 0;
76 }
77
78 /* first is true if we read the frame header */
81 {
84 int len, fill_size, size1, frame_offset,
id;
85
87 while (size > 0) {
88 redo:
90 if (len < 0)
91 return -1;
92 if (len > size)
94 if (len == 0) {
97 retry_read:
102 }
106 return -1;
113 return -1;
114 /* if first packet or resynchronization packet, we must
115 handle it specifically */
117 if (!frame_offset) {
118 /* This packet has no frame headers in it */
121 goto retry_read;
122 }
123 /* This is bad, we cannot find a valid frame header */
124 return 0;
125 }
128 return -1;
130 if (!header)
131 break;
132 } else {
134 }
135 goto redo;
136 }
141 header = 0;
142 }
144 }
145
146 /* ensure that acutal seeking happens between FFM_PACKET_SIZE
147 and file_size - FFM_PACKET_SIZE */
149 {
152 int64_t pos;
153
156 av_dlog(s,
"seek to %"PRIx64
" -> %"PRIx64
"\n", pos1, pos);
158 }
159
161 {
163 int64_t dts;
164
168 av_dlog(s,
"dts=%0.6f\n", dts / 1000000.0);
169 return dts;
170 }
171
173 {
177 //int64_t orig_write_index = ffm->write_index;
178 int64_t pos_min, pos_max;
179 int64_t pts_start;
181
182
183 pos_min = 0;
185
186 pts_start =
get_dts(s, pos_min);
187
189
190 if (pts - 100000 > pts_start)
192
194
195 pts_start =
get_dts(s, pos_min);
196
198
199 if (pts - 100000 <= pts_start) {
200 while (1) {
201 int64_t newpos;
202 int64_t newpts;
203
205
206 if (newpos == pos_min)
207 break;
208
210
211 if (newpts - 100000 <= pts) {
212 pos_max = newpos;
213 pts = newpts;
214 } else {
215 pos_min = newpos;
216 }
217 }
219 }
220
223 }
224
225
227 {
228 int i;
229
232
233 return 0;
234 }
235
237 {
239 size_t newsize;
241 if (!*conf)
242 return 0;
245 *conf = 0;
246 return 0;
247 }
254 return 0;
255 }
256
258 {
264 int f_main = 0, f_cprv, f_stvi, f_stau;
267
273 goto fail;
274 }
275
277 /* get also filesize */
282 } else {
283 ffm->
file_size = (UINT64_C(1) << 63) - 1;
284 }
285
290 char rc_eq_buf[128];
291
292 if(!id)
293 break;
294
295 switch(id) {
296 case MKBETAG(
'M',
'A',
'I',
'N'):
297 if (f_main++) {
299 goto fail;
300 }
303 break;
304 case MKBETAG(
'C',
'O',
'M',
'M'):
305 f_cprv = f_stvi = f_stau = 0;
307 if (!st) {
309 goto fail;
310 }
311
313
315 /* generic info */
325 }
326 break;
327 case MKBETAG(
'S',
'T',
'V',
'I'):
328 if (f_stvi++) {
330 goto fail;
331 }
344 avio_get_str(pb, INT_MAX, rc_eq_buf,
sizeof(rc_eq_buf));
376 break;
377 case MKBETAG(
'S',
'T',
'A',
'U'):
378 if (f_stau++) {
380 goto fail;
381 }
385 break;
386 case MKBETAG(
'C',
'P',
'R',
'V'):
387 if (f_cprv++) {
389 goto fail;
390 }
394 if (!buffer) {
396 goto fail;
397 }
400 goto fail;
401 }
402 break;
403 case MKBETAG(
'S',
'2',
'V',
'I'):
404 if (f_stvi++) {
406 goto fail;
407 }
409 if (!buffer) {
411 goto fail;
412 }
416 goto fail;
417 break;
418 case MKBETAG(
'S',
'2',
'A',
'U'):
419 if (f_stau++) {
421 goto fail;
422 }
424 if (!buffer) {
426 goto fail;
427 }
431 break;
432 }
434 }
435
436 /* get until end of block reached */
439
440 /* init packet demux */
447 return 0;
448 fail:
451 }
452
454 {
461
462 /* header */
464 if (tag ==
MKTAG(
'F',
'F',
'M',
'2'))
466 if (tag !=
MKTAG(
'F',
'F',
'M',
'1'))
467 goto fail;
470 goto fail;
472 /* get also filesize */
477 } else {
478 ffm->
file_size = (UINT64_C(1) << 63) - 1;
479 }
480
483 /* read each stream */
485 char rc_eq_buf[128];
486
488 if (!st)
489 goto fail;
490
492
494 /* generic info */
501 /* specific info */
516 avio_get_str(pb, INT_MAX, rc_eq_buf,
sizeof(rc_eq_buf));
548 break;
553 break;
554 default:
555 goto fail;
556 }
560 }
561 }
562
563 /* get until end of block reached */
566
567 /* init packet demux */
574 return 0;
575 fail:
577 return -1;
578 }
579
580 /* return < 0 if eof */
582 {
586
591
592 av_dlog(s,
"pos=%08"PRIx64
" spos=%"PRIx64
", write_index=%"PRIx64
" size=%"PRIx64
"\n",
596 return -1;
599 return -1;
601 /* fall through */
606
608
611 }
617 return -1;
618 }
622
625 /* bad case: desynchronized packet. we cancel all the packet loading */
627 return -1;
628 }
632 else
635 break;
636 }
637 return 0;
638 }
639
640 /* seek to a given time in the file. The file read pointer is
641 positioned at or before pts. XXX: the following code is quite
642 approximative */
644 {
646 int64_t pos_min, pos_max, pos;
647 int64_t pts_min, pts_max,
pts;
648 double pos1;
649
650 av_dlog(s,
"wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
651 /* find the position using linear interpolation (better than
652 dichotomy in typical cases) */
657 } else {
660 }
661 } else {
664 }
665 while (pos_min <= pos_max) {
668 if (pts_min > wanted_pts || pts_max <= wanted_pts) {
669 pos = pts_min > wanted_pts ? pos_min : pos_max;
670 goto found;
671 }
672 /* linear interpolation */
673 pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
674 (double)(pts_max - pts_min);
676 if (pos <= pos_min)
677 pos = pos_min;
678 else if (pos >= pos_max)
679 pos = pos_max;
681 /* check if we are lucky */
682 if (pts == wanted_pts) {
683 goto found;
684 } else if (pts > wanted_pts) {
686 } else {
688 }
689 }
691
692 found:
694 return -1;
695
696 /* reset read state */
701
702 return 0;
703 }
704
706 {
707 if (
708 p->
buf[0] ==
'F' && p->
buf[1] ==
'F' && p->
buf[2] ==
'M' &&
709 (p->
buf[3] ==
'1' || p->
buf[3] ==
'2'))
711 return 0;
712 }
713
723 };