Mercurial > libavformat.hg
annotate tcp.c @ 1942:70b741fa63eb libavformat
The NSV demuxer assumes that a video frame's timestamp increases by one on each
frame, but some low-bitrate NSV files omit video frames for some NSV frames,
and expect the timestamp to increase by one every NSV frame. This is noticeable
in 64vp3.nsv where the video runs several times faster than the audio. Fix this
by unconditionally incrementing the video's timestamp with each NSV frame.
patch by David Conrad, umovimus gmail com
author | diego |
---|---|
date | Wed, 21 Mar 2007 11:05:35 +0000 |
parents | d85795da84ab |
children | b6b8a9836cf9 |
rev | line source |
---|---|
0 | 1 /* |
2 * TCP protocol | |
3 * Copyright (c) 2002 Fabrice Bellard. | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
923
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
923
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
923
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
923
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
923
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
923
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
21 #include "avformat.h" | |
22 #include <unistd.h> | |
1754 | 23 #include "network.h" |
180 | 24 #include <sys/time.h> |
25 #include <fcntl.h> | |
0 | 26 |
27 typedef struct TCPContext { | |
28 int fd; | |
29 } TCPContext; | |
30 | |
31 /* resolve host with also IP address parsing */ | |
32 int resolve_host(struct in_addr *sin_addr, const char *hostname) | |
33 { | |
34 struct hostent *hp; | |
35 | |
36 if ((inet_aton(hostname, sin_addr)) == 0) { | |
37 hp = gethostbyname(hostname); | |
38 if (!hp) | |
39 return -1; | |
40 memcpy (sin_addr, hp->h_addr, sizeof(struct in_addr)); | |
41 } | |
42 return 0; | |
43 } | |
44 | |
45 /* return non zero if error */ | |
46 static int tcp_open(URLContext *h, const char *uri, int flags) | |
47 { | |
48 struct sockaddr_in dest_addr; | |
49 char hostname[1024], *q; | |
50 int port, fd = -1; | |
683
095009fc2f35
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
511
diff
changeset
|
51 TCPContext *s = NULL; |
180 | 52 fd_set wfds; |
53 int fd_max, ret; | |
54 struct timeval tv; | |
55 socklen_t optlen; | |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
56 char proto[1024],path[1024],tmp[1024]; // PETR: protocol and path strings |
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
57 |
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
58 url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), |
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
59 &port, path, sizeof(path), uri); // PETR: use url_split |
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
60 if (strcmp(proto,"tcp")) goto fail; // PETR: check protocol |
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
61 if ((q = strchr(hostname,'@'))) { strcpy(tmp,q+1); strcpy(hostname,tmp); } // PETR: take only the part after '@' for tcp protocol |
885 | 62 |
0 | 63 s = av_malloc(sizeof(TCPContext)); |
64 if (!s) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
65 return AVERROR(ENOMEM); |
0 | 66 h->priv_data = s; |
885 | 67 |
0 | 68 if (port <= 0 || port >= 65536) |
69 goto fail; | |
885 | 70 |
0 | 71 dest_addr.sin_family = AF_INET; |
72 dest_addr.sin_port = htons(port); | |
73 if (resolve_host(&dest_addr.sin_addr, hostname) < 0) | |
74 goto fail; | |
75 | |
1810
d85795da84ab
change PF_INET to AF_INET to be consistent in the whole project. PF_INET is deprecated, while AF_INET is referred by the POSIX standards
alex
parents:
1787
diff
changeset
|
76 fd = socket(AF_INET, SOCK_STREAM, 0); |
0 | 77 if (fd < 0) |
78 goto fail; | |
180 | 79 fcntl(fd, F_SETFL, O_NONBLOCK); |
885 | 80 |
180 | 81 redo: |
885 | 82 ret = connect(fd, (struct sockaddr *)&dest_addr, |
180 | 83 sizeof(dest_addr)); |
84 if (ret < 0) { | |
85 if (errno == EINTR) | |
86 goto redo; | |
87 if (errno != EINPROGRESS) | |
88 goto fail; | |
0 | 89 |
180 | 90 /* wait until we are connected or until abort */ |
91 for(;;) { | |
92 if (url_interrupt_cb()) { | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
93 ret = AVERROR(EINTR); |
180 | 94 goto fail1; |
95 } | |
96 fd_max = fd; | |
97 FD_ZERO(&wfds); | |
98 FD_SET(fd, &wfds); | |
99 tv.tv_sec = 0; | |
100 tv.tv_usec = 100 * 1000; | |
101 ret = select(fd_max + 1, NULL, &wfds, NULL, &tv); | |
102 if (ret > 0 && FD_ISSET(fd, &wfds)) | |
103 break; | |
104 } | |
885 | 105 |
180 | 106 /* test error */ |
107 optlen = sizeof(ret); | |
108 getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); | |
109 if (ret != 0) | |
110 goto fail; | |
111 } | |
0 | 112 s->fd = fd; |
113 return 0; | |
114 | |
115 fail: | |
482 | 116 ret = AVERROR_IO; |
180 | 117 fail1: |
0 | 118 if (fd >= 0) |
1670 | 119 closesocket(fd); |
0 | 120 av_free(s); |
180 | 121 return ret; |
0 | 122 } |
123 | |
65 | 124 static int tcp_read(URLContext *h, uint8_t *buf, int size) |
0 | 125 { |
126 TCPContext *s = h->priv_data; | |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
127 int len, fd_max, ret; |
180 | 128 fd_set rfds; |
129 struct timeval tv; | |
0 | 130 |
385
2f56d366a787
no read loop tcp/http and http CRLF fix by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
261
diff
changeset
|
131 for (;;) { |
180 | 132 if (url_interrupt_cb()) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
133 return AVERROR(EINTR); |
180 | 134 fd_max = s->fd; |
135 FD_ZERO(&rfds); | |
136 FD_SET(s->fd, &rfds); | |
137 tv.tv_sec = 0; | |
138 tv.tv_usec = 100 * 1000; | |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
139 ret = select(fd_max + 1, &rfds, NULL, NULL, &tv); |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
140 if (ret > 0 && FD_ISSET(s->fd, &rfds)) { |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
141 len = recv(s->fd, buf, size, 0); |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
142 if (len < 0) { |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
143 if (errno != EINTR && errno != EAGAIN) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
144 return AVERROR(errno); |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
145 } else return len; |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
146 } else if (ret < 0) { |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
147 return -1; |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
148 } |
0 | 149 } |
150 } | |
151 | |
65 | 152 static int tcp_write(URLContext *h, uint8_t *buf, int size) |
0 | 153 { |
154 TCPContext *s = h->priv_data; | |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
155 int ret, size1, fd_max, len; |
180 | 156 fd_set wfds; |
157 struct timeval tv; | |
0 | 158 |
159 size1 = size; | |
160 while (size > 0) { | |
180 | 161 if (url_interrupt_cb()) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
162 return AVERROR(EINTR); |
180 | 163 fd_max = s->fd; |
164 FD_ZERO(&wfds); | |
165 FD_SET(s->fd, &wfds); | |
166 tv.tv_sec = 0; | |
167 tv.tv_usec = 100 * 1000; | |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
168 ret = select(fd_max + 1, NULL, &wfds, NULL, &tv); |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
169 if (ret > 0 && FD_ISSET(s->fd, &wfds)) { |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
170 len = send(s->fd, buf, size, 0); |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
171 if (len < 0) { |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
172 if (errno != EINTR && errno != EAGAIN) |
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
173 return AVERROR(errno); |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
174 continue; |
261
5f27f90ed496
Fix a very nasty problem with extra bytes appearing in TCP data streams.
philipjsg
parents:
229
diff
changeset
|
175 } |
388
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
176 size -= len; |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
177 buf += len; |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
178 } else if (ret < 0) { |
9af30d452a0a
tcp select() check and enables pressing 'q' when reading/(writing) from
michael
parents:
385
diff
changeset
|
179 return -1; |
261
5f27f90ed496
Fix a very nasty problem with extra bytes appearing in TCP data streams.
philipjsg
parents:
229
diff
changeset
|
180 } |
0 | 181 } |
182 return size1 - size; | |
183 } | |
184 | |
185 static int tcp_close(URLContext *h) | |
186 { | |
187 TCPContext *s = h->priv_data; | |
188 closesocket(s->fd); | |
189 av_free(s); | |
190 return 0; | |
191 } | |
192 | |
193 URLProtocol tcp_protocol = { | |
194 "tcp", | |
195 tcp_open, | |
196 tcp_read, | |
197 tcp_write, | |
198 NULL, /* seek */ | |
199 tcp_close, | |
200 }; |