2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "libavformat/avformat.h"
22 #include "libavformat/avio.h"
27 #include "libmpdemux/demuxer.h"
29 static int fill_buffer(stream_t
*s
, char *buffer
, int max_len
)
31 AVIOContext
*avio
= s
->priv
;
32 int r
= avio_read(avio
, buffer
, max_len
);
33 return (r
<= 0) ? -1 : r
;
36 static int write_buffer(stream_t
*s
, char *buffer
, int len
)
38 AVIOContext
*avio
= s
->priv
;
39 avio_write(avio
, buffer
, len
);
46 static int seek(stream_t
*s
, off_t newpos
)
48 AVIOContext
*avio
= s
->priv
;
50 if (avio_seek(avio
, s
->pos
, SEEK_SET
) < 0) {
57 static int control(stream_t
*s
, int cmd
, void *arg
)
59 AVIOContext
*avio
= s
->priv
;
63 case STREAM_CTRL_GET_SIZE
:
64 size
= avio_size(avio
);
70 case STREAM_CTRL_SEEK_TO_TIME
:
72 ts
= pts
* AV_TIME_BASE
;
73 ts
= avio_seek_time(avio
, -1, ts
, 0);
78 return STREAM_UNSUPPORTED
;
81 static void close_f(stream_t
*stream
)
83 AVIOContext
*avio
= stream
->priv
;
84 /* NOTE: As of 2011 write streams must be manually flushed before close.
85 * Currently write_buffer() always flushes them after writing.
86 * avio_close() could return an error, but we have no way to return that
87 * with the current stream API.
92 static const char * const prefix
[] = { "lavf://", "ffmpeg://" };
94 static int open_f(stream_t
*stream
, int mode
, void *opts
, int *file_format
)
98 AVIOContext
*avio
= NULL
;
99 int res
= STREAM_ERROR
;
101 if (mode
== STREAM_READ
)
102 flags
= AVIO_FLAG_READ
;
103 else if (mode
== STREAM_WRITE
)
104 flags
= AVIO_FLAG_WRITE
;
106 mp_msg(MSGT_OPEN
, MSGL_ERR
, "[ffmpeg] Unknown open mode %d\n", mode
);
107 res
= STREAM_UNSUPPORTED
;
112 filename
= stream
->url
;
114 mp_msg(MSGT_OPEN
, MSGL_ERR
, "[ffmpeg] No URL\n");
117 for (int i
= 0; i
< sizeof(prefix
) / sizeof(prefix
[0]); i
++)
118 if (!strncmp(filename
, prefix
[i
], strlen(prefix
[i
])))
119 filename
+= strlen(prefix
[i
]);
120 if (!strncmp(filename
, "rtsp:", 5)) {
121 /* This is handled as a special demuxer, without a separate
122 * stream layer. demux_lavf will do all the real work.
124 stream
->type
= STREAMTYPE_STREAM
;
126 *file_format
= DEMUXER_TYPE_LAVF
;
127 stream
->lavf_type
= "rtsp";
130 mp_msg(MSGT_OPEN
, MSGL_V
, "[ffmpeg] Opening %s\n", filename
);
132 if (avio_open(&avio
, filename
, flags
) < 0)
135 char *rtmp
[] = {"rtmp:", "rtmpt:", "rtmpe:", "rtmpte:", "rtmps:"};
136 for (int i
= 0; i
< FF_ARRAY_ELEMS(rtmp
); i
++)
137 if (!strncmp(filename
, rtmp
[i
], strlen(rtmp
[i
]))) {
138 *file_format
= DEMUXER_TYPE_LAVF
;
139 stream
->lavf_type
= "flv";
142 int64_t size
= avio_size(avio
);
144 stream
->end_pos
= size
;
145 stream
->type
= STREAMTYPE_FILE
;
147 if (!avio
->seekable
) {
148 stream
->type
= STREAMTYPE_STREAM
;
151 stream
->fill_buffer
= fill_buffer
;
152 stream
->write_buffer
= write_buffer
;
153 stream
->control
= control
;
154 stream
->close
= close_f
;
161 const stream_info_t stream_info_ffmpeg
= {
167 { "lavf", "ffmpeg", "rtmp", "rtsp", NULL
},
169 1 // Urls are an option string