Mercurial > mplayer.hg
annotate stream/stream_vcd.c @ 24589:9118be6575da
demux_audio.c: Fix timestamp handling
The code calculated the pts values of audio packets by adding the length
of the current packet to the pts of the previous one. The length of the
previous packet should be added instead. This broke WAV timestamps near
the end of the stream where a short packet occurs.
Change the code to store the pts of the next packet instead of the last
one. This fixes the WAV timestamps and allows some simplifications.
MP3 timestamps are not affected as packets are always treated as
constant decoded length, and FLAC timestamps still have worse problems
(FLAC is treated as as if it was constant bitrate even though it isn't).
Also store the timestamps as double instead of float.
author | uau |
---|---|
date | Mon, 24 Sep 2007 21:49:56 +0000 |
parents | d261f5109660 |
children | c1d17bd6683c |
rev | line source |
---|---|
9886 | 1 |
2 #include "config.h" | |
3 | |
22506 | 4 #ifdef WIN32 |
5 #include <windows.h> | |
6 #endif | |
7 | |
9886 | 8 #include "mp_msg.h" |
9 #include "stream.h" | |
10 #include "help_mp.h" | |
17012 | 11 #include "m_option.h" |
12 #include "m_struct.h" | |
9886 | 13 |
10121
d42177a0da2a
Changed the STREAMING defines to MPLAYER_NETWORK to avoid name definition clash.
bertrand
parents:
9886
diff
changeset
|
14 #include <fcntl.h> |
9886 | 15 #include <stdlib.h> |
16 #include <unistd.h> | |
22506 | 17 #ifndef WIN32 |
9886 | 18 #include <sys/ioctl.h> |
22506 | 19 #endif |
9886 | 20 #include <errno.h> |
21 | |
23857 | 22 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) |
9886 | 23 #include "vcd_read_fbsd.h" |
13681
e52daf7f3bcc
enable vcd for all darwin based sys not only mac osx
nplourde
parents:
13678
diff
changeset
|
24 #elif defined(SYS_DARWIN) |
e52daf7f3bcc
enable vcd for all darwin based sys not only mac osx
nplourde
parents:
13678
diff
changeset
|
25 #include "vcd_read_darwin.h" |
22506 | 26 #elif defined(WIN32) |
27 #include "vcd_read_win32.h" | |
9886 | 28 #else |
29 #include "vcd_read.h" | |
30 #endif | |
31 | |
21926
a8cd73869242
at open() assign *file_format=DEMUXER_TYPE_MPEG_PS to avoid useless demuxer probing
nicodvb
parents:
21848
diff
changeset
|
32 #include "libmpdemux/demuxer.h" |
a8cd73869242
at open() assign *file_format=DEMUXER_TYPE_MPEG_PS to avoid useless demuxer probing
nicodvb
parents:
21848
diff
changeset
|
33 |
10591 | 34 extern char *cdrom_device; |
35 | |
9886 | 36 static struct stream_priv_s { |
37 int track; | |
38 char* device; | |
39 } stream_priv_dflts = { | |
40 1, | |
10591 | 41 NULL |
9886 | 42 }; |
43 | |
44 #define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) | |
45 /// URL definition | |
46 static m_option_t stream_opts_fields[] = { | |
47 { "track", ST_OFF(track), CONF_TYPE_INT, M_OPT_MIN, 1, 0, NULL }, | |
48 { "device", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL}, | |
49 /// For url parsing | |
50 { "hostname", ST_OFF(track), CONF_TYPE_INT, M_OPT_MIN, 1, 0, NULL }, | |
51 { "filename", ST_OFF(device), CONF_TYPE_STRING, 0, 0 ,0, NULL}, | |
52 { NULL, NULL, 0, 0, 0, 0, NULL } | |
53 }; | |
54 static struct m_struct_st stream_opts = { | |
55 "vcd", | |
56 sizeof(struct stream_priv_s), | |
57 &stream_priv_dflts, | |
58 stream_opts_fields | |
59 }; | |
60 | |
61 static int fill_buffer(stream_t *s, char* buffer, int max_len){ | |
15912 | 62 if(s->pos > s->end_pos) /// don't past end of current track |
63 return 0; | |
9886 | 64 return vcd_read(s->priv,buffer); |
65 } | |
66 | |
67 static int seek(stream_t *s,off_t newpos) { | |
68 s->pos = newpos; | |
69 vcd_set_msf(s->priv,s->pos/VCD_SECTOR_DATA); | |
70 return 1; | |
71 } | |
72 | |
73 static void close_s(stream_t *stream) { | |
74 free(stream->priv); | |
75 } | |
76 | |
77 static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { | |
78 struct stream_priv_s* p = (struct stream_priv_s*)opts; | |
22775
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
79 int ret,ret2,f,sect,tmp; |
9886 | 80 mp_vcd_priv_t* vcd; |
21848 | 81 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) |
9886 | 82 int bsize = VCD_SECTOR_SIZE; |
83 #endif | |
22506 | 84 #ifdef WIN32 |
85 HANDLE hd; | |
86 char device[] = "\\\\.\\?:"; | |
87 #endif | |
9886 | 88 |
22506 | 89 if(mode != STREAM_READ |
90 #ifdef WIN32 | |
91 || GetVersion() > 0x80000000 // Win9x | |
92 #endif | |
93 ) { | |
9886 | 94 m_struct_free(&stream_opts,opts); |
24257 | 95 return STREAM_UNSUPPORTED; |
9886 | 96 } |
97 | |
10591 | 98 if (!p->device) { |
99 if(cdrom_device) | |
100 p->device = strdup(cdrom_device); | |
101 else | |
102 p->device = strdup(DEFAULT_CDROM_DEVICE); | |
103 } | |
104 | |
22506 | 105 #ifdef WIN32 |
106 device[4] = p->device[0]; | |
107 /* open() can't be used for devices so do it the complicated way */ | |
108 hd = CreateFile(device, GENERIC_READ, FILE_SHARE_READ, NULL, | |
109 OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); | |
110 f = _open_osfhandle((long)hd, _O_RDONLY); | |
111 #else | |
9886 | 112 f=open(p->device,O_RDONLY); |
22506 | 113 #endif |
9886 | 114 if(f<0){ |
115 mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_CdDevNotfound,p->device); | |
116 m_struct_free(&stream_opts,opts); | |
117 return STREAM_ERROR; | |
118 } | |
119 | |
120 vcd = vcd_read_toc(f); | |
121 if(!vcd) { | |
122 mp_msg(MSGT_OPEN,MSGL_ERR,"Failed to get cd toc\n"); | |
123 close(f); | |
124 m_struct_free(&stream_opts,opts); | |
125 return STREAM_ERROR; | |
126 } | |
127 ret2=vcd_get_track_end(vcd,p->track); | |
128 if(ret2<0){ | |
129 mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (get)\n"); | |
130 close(f); | |
131 free(vcd); | |
132 m_struct_free(&stream_opts,opts); | |
133 return STREAM_ERROR; | |
134 } | |
135 ret=vcd_seek_to_track(vcd,p->track); | |
136 if(ret<0){ | |
137 mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_ErrTrackSelect " (seek)\n"); | |
138 close(f); | |
139 free(vcd); | |
140 m_struct_free(&stream_opts,opts); | |
141 return STREAM_ERROR; | |
142 } | |
22775
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
143 /* search forward up to at most 3 seconds to skip leading margin */ |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
144 sect = ret / VCD_SECTOR_DATA; |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
145 for (tmp = sect; tmp < sect + 3 * 75; tmp++) { |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
146 char mem[VCD_SECTOR_DATA]; |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
147 //since MPEG packs are block-aligned we stop discarding sectors if they are non-null |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
148 if (vcd_read(vcd, mem) != VCD_SECTOR_DATA || mem[2] || mem[3]) |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
149 break; |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
150 } |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
151 mp_msg(MSGT_OPEN, MSGL_DBG2, "%d leading sectors skipped\n", tmp - sect); |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
152 vcd_set_msf(vcd, tmp); |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
153 ret = tmp * VCD_SECTOR_DATA; |
f6dc5fd2b347
at open() discard front margin/empty sectors (fixes demuxing by libavformat); patch by Zuxy meng
nicodvb
parents:
22506
diff
changeset
|
154 |
9886 | 155 mp_msg(MSGT_OPEN,MSGL_V,"VCD start byte position: 0x%X end: 0x%X\n",ret,ret2); |
156 | |
21848 | 157 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) |
9886 | 158 if (ioctl (f, CDRIOCSETBLOCKSIZE, &bsize) == -1) { |
159 mp_msg(MSGT_OPEN,MSGL_WARN,"Error in CDRIOCSETBLOCKSIZE"); | |
160 } | |
161 #endif | |
162 | |
163 stream->fd = f; | |
164 stream->type = STREAMTYPE_VCD; | |
165 stream->sector_size = VCD_SECTOR_DATA; | |
166 stream->start_pos=ret; | |
167 stream->end_pos=ret2; | |
168 stream->priv = vcd; | |
169 | |
170 stream->fill_buffer = fill_buffer; | |
171 stream->seek = seek; | |
172 stream->close = close_s; | |
21926
a8cd73869242
at open() assign *file_format=DEMUXER_TYPE_MPEG_PS to avoid useless demuxer probing
nicodvb
parents:
21848
diff
changeset
|
173 *file_format = DEMUXER_TYPE_MPEG_PS; |
9886 | 174 |
175 m_struct_free(&stream_opts,opts); | |
176 return STREAM_OK; | |
177 } | |
178 | |
179 stream_info_t stream_info_vcd = { | |
180 "Video CD", | |
181 "vcd", | |
182 "Albeu", | |
183 "based on the code from ???", | |
184 open_s, | |
185 { "vcd", NULL }, | |
186 &stream_opts, | |
187 1 // Urls are an option string | |
188 }; |