annotate libmpdemux/demux_nsv.c @ 27319:09cf111f68b8

Revert to previous dependency checking behavior. Take included header files into account when generating dependency files. This has problems when header files are removed or renamed, but does not silently miscompile files.
author diego
date Sat, 26 Jul 2008 18:36:48 +0000
parents c8a489c8cae8
children d643e4643313
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
1
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
2 /*
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
3 * Nullsoft Streaming Video demuxer
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
4 * for MPlayer
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
5 * by Reza Jelveh <reza.jelveh@tuhh.de>
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
6 * seeking and PCM audio not yet supported
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
7 * PCM needs extra audio chunk "miniheader" parsing
12181
12ddc64011fe Add license, remove bogus comment as told by Reza Jelveh, the author.
diego
parents: 12179
diff changeset
8 * Based on A'rpis G2 work
12ddc64011fe Add license, remove bogus comment as told by Reza Jelveh, the author.
diego
parents: 12179
diff changeset
9 * Licence: GPL
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
10 */
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
11
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
12 #include <stdio.h>
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
13 #include <stdlib.h>
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
14 #include <unistd.h>
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
15
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
16 #include "config.h"
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
17 #include "mp_msg.h"
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
18 #include "help_mp.h"
22605
4d81dbdf46b9 Add explicit location for headers from the stream/ directory.
diego
parents: 20473
diff changeset
19 #include "stream/stream.h"
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
20 #include "demuxer.h"
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
21 #include "stheader.h"
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
22
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
23 typedef struct {
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
24 float v_pts;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
25 int video_pack_no;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
26 unsigned int a_format;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
27 unsigned int v_format;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
28 unsigned char fps;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
29 } nsv_priv_t;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
30
18251
fdb789f1a99a Increase HEADER_SEARCH_SIZE, fixes high-bitrate streams from demoscene.tv.
diego
parents: 17636
diff changeset
31 #define HEADER_SEARCH_SIZE 256000
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
32
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
33
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
34 /**
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
35 * Seeking still to be implemented
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
36 */
17636
b849a99cdc3c Second-try commit of this patch.
corey
parents: 17569
diff changeset
37 static void demux_seek_nsv ( demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags )
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
38 {
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
39 // seeking is not yet implemented
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
40 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
41
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
42
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
43 static int demux_nsv_fill_buffer ( demuxer_t *demuxer, demux_stream_t *ds )
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
44 {
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
45 unsigned char hdr[17];
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
46 // for the extra data
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
47 unsigned char aux[6];
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
48 int i_aux = 0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
49 // videolen = audio chunk length, audiolen = video chunk length
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
50 int videolen,audiolen;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
51
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
52 sh_video_t *sh_video = demuxer->video->sh;
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
53 sh_audio_t *sh_audio = demuxer->audio->sh;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
54
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
55 nsv_priv_t * priv = demuxer->priv;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
56
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
57 // if the audio/video chunk has no new header the first 2 bytes will be discarded 0xBEEF
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
58 // or rather 0xEF 0xBE
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
59 stream_read(demuxer->stream,hdr,7);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
60 if(stream_eof(demuxer->stream)) return 0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
61 // sometimes instead of 0xBEEF as described for the next audio/video chunk we get
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
62 // a whole new header
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
63
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
64 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %08X %08X\n",hdr[0]<<8|hdr[1],stream_tell(demuxer->stream));
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
65 switch(hdr[0]<<8|hdr[1]) {
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
66 case 0x4E53:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
67 if(hdr[2]==0x56 && hdr[3]==0x73){
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
68 // NSVs
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
69 // get the header since there is no more metaheader after the first one
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
70 // there is no more need to skip that
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
71 stream_read(demuxer->stream,hdr+7,17-7);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
72 stream_read(demuxer->stream,hdr,7);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
73 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
74 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
75
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
76 case 0xEFBE:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
77 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
78
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
79 default:
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
80 mp_dbg(MSGT_DEMUX,MSGL_WARN,"demux_nsv: sync lost\n");
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
81 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
82 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
83
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
84 if (sh_video)
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
85 sh_video->pts = priv->v_pts =demuxer->video->pts= priv->video_pack_no *
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
86 (float)sh_video->frametime;
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
87 else
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
88 priv->v_pts = priv->video_pack_no;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
89
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
90 demuxer->filepos=stream_tell(demuxer->stream);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
91
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
92
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
93 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %08X: %02X %02X | %02X %02X %02X | %02X %02X \n",
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
94 (int)demuxer->filepos, hdr[0],hdr[1],hdr[2],hdr[3],hdr[4],hdr[5],hdr[6]);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
95
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
96 // read video:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
97 videolen=(hdr[2]>>4)|(hdr[3]<<4)|(hdr[4]<<0xC);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
98 //check if we got extra data like subtitles here
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
99 if( (hdr[2]&0x0f) != 0x0 ) {
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
100 stream_read( demuxer->stream, aux, 6);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
101
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
102 i_aux = aux[0]|aux[1]<<8;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
103 // We skip this extra data
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
104 stream_skip( demuxer->stream, i_aux );
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
105 i_aux+=6;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
106 videolen -= i_aux;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
107 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
108
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
109
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
110 // we need to return an empty packet when the
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
111 // video frame is empty otherwise the stream will fasten up
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
112 if(sh_video) {
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
113 if( (hdr[2]&0x0f) != 0x0 )
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
114 ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos-i_aux,0);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
115 else
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
116 ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos,0);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
117 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
118 else
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
119 stream_skip(demuxer->stream,videolen);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
120
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
121 // read audio:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
122 audiolen=(hdr[5])|(hdr[6]<<8);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
123 // we need to return an empty packet when the
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
124 // audio frame is empty otherwise the stream will fasten up
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
125 if(sh_audio) {
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
126 ds_read_packet(demuxer->audio,demuxer->stream,audiolen,priv->v_pts,demuxer->filepos+videolen,0);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
127 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
128 else
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
129 stream_skip(demuxer->stream,audiolen);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
130
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
131 ++priv->video_pack_no;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
132
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
133 return 1;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
134
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
135 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
136
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
137
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
138 static demuxer_t* demux_open_nsv ( demuxer_t* demuxer )
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
139 {
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
140 // last 2 bytes 17 and 18 are unknown but right after that comes the length
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
141 unsigned char hdr[17];
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
142 int videolen,audiolen;
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
143 unsigned char buf[10];
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
144 sh_video_t *sh_video = NULL;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
145 sh_audio_t *sh_audio = NULL;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
146
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
147
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
148 nsv_priv_t * priv = malloc(sizeof(nsv_priv_t));
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
149 demuxer->priv=priv;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
150 priv->video_pack_no=0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
151
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
152 /* disable seeking yet to be fixed*/
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
153 demuxer->seekable = 0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
154
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
155 stream_read(demuxer->stream,hdr,4);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
156 if(stream_eof(demuxer->stream)) return 0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
157
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
158 if(hdr[0]==0x4E && hdr[1]==0x53 && hdr[2]==0x56){
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
159 // NSV header!
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
160 if(hdr[3]==0x73){
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
161 // NSVs
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
162 stream_read(demuxer->stream,hdr+4,17-4);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
163 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
164
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
165 if(hdr[3]==0x66){
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
166 // NSVf
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
167 int len=stream_read_dword_le(demuxer->stream);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
168 // TODO: parse out metadata!!!!
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
169 stream_skip(demuxer->stream,len-8);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
170
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
171 // NSVs
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
172 stream_read(demuxer->stream,hdr,17);
20470
054516eecb9b Better check for non-broken NSVf-header to avoid incorrect detection.
reimar
parents: 18885
diff changeset
173 if (stream_eof(demuxer->stream) || strncmp(hdr, "NSVs", 4))
054516eecb9b Better check for non-broken NSVf-header to avoid incorrect detection.
reimar
parents: 18885
diff changeset
174 return 0;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
175 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
176
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
177 // dummy debug message
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
178 mp_msg(MSGT_DEMUX,MSGL_V,"demux_nsv: Header: %.12s\n",hdr);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
179
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
180 // bytes 8-11 audio codec fourcc
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
181 // PCM fourcc needs extra parsing for every audio chunk, yet to implement
12896
e60cf1255df2 Fix -nosound and -novideo (bug #28)
rtognimp
parents: 12277
diff changeset
182 if((demuxer->audio->id != -2) && strncmp(hdr+8,"NONE", 4)){//&&strncmp(hdr+8,"VLB ", 4)){
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
183 sh_audio = new_sh_audio ( demuxer, 0 );
26295
c8a489c8cae8 Set demuxer->audio->id to avoid breakage due to r26301
reimar
parents: 25707
diff changeset
184 demuxer->audio->id = 0;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
185 demuxer->audio->sh = sh_audio;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
186 sh_audio->format=mmioFOURCC(hdr[8],hdr[9],hdr[10],hdr[11]);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
187 sh_audio->ds = demuxer->audio;
12896
e60cf1255df2 Fix -nosound and -novideo (bug #28)
rtognimp
parents: 12277
diff changeset
188 priv->a_format=mmioFOURCC(hdr[8],hdr[9],hdr[10],hdr[11]);
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
189 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
190
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
191 // store hdr fps
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
192 priv->fps=hdr[16];
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
193
12896
e60cf1255df2 Fix -nosound and -novideo (bug #28)
rtognimp
parents: 12277
diff changeset
194 if ((demuxer->video->id != -2) && strncmp(hdr+4,"NONE", 4)) {
12198
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
195 /* Create a new video stream header */
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
196 sh_video = new_sh_video ( demuxer, 0 );
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
197
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
198 /* Make sure the demuxer knows about the new video stream header
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
199 * (even though new_sh_video() ought to take care of it)
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
200 */
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
201 demuxer->video->sh = sh_video;
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
202
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
203 /* Make sure that the video demuxer stream header knows about its
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
204 * parent video demuxer stream (this is getting wacky), or else
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
205 * video_read_properties() will choke
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
206 */
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
207 sh_video->ds = demuxer->video;
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
208
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
209 // bytes 4-7 video codec fourcc
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
210 priv->v_format = sh_video->format=mmioFOURCC(hdr[4],hdr[5],hdr[6],hdr[7]);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
211
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
212 // new video stream! parse header
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
213 sh_video->disp_w=hdr[12]|(hdr[13]<<8);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
214 sh_video->disp_h=hdr[14]|(hdr[15]<<8);
18885
5c8acc972551 rm unnecesary casts from void* - part 4
reynaldo
parents: 18251
diff changeset
215 sh_video->bih=calloc(1,sizeof(BITMAPINFOHEADER));
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
216 sh_video->bih->biSize=sizeof(BITMAPINFOHEADER);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
217 sh_video->bih->biPlanes=1;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
218 sh_video->bih->biBitCount=24;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
219 sh_video->bih->biWidth=hdr[12]|(hdr[13]<<8);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
220 sh_video->bih->biHeight=hdr[14]|(hdr[15]<<8);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
221 memcpy(&sh_video->bih->biCompression,hdr+4,4);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
222 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
223
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
224 // here we search for the correct keyframe
12275
3bd70d9bebb7 Fix VP62 keyframe search
rtognimp
parents: 12272
diff changeset
225 // vp6 keyframe is when the 2nd byte of the vp6 header is
3bd70d9bebb7 Fix VP62 keyframe search
rtognimp
parents: 12272
diff changeset
226 // 0x36 for VP61 and 0x46 for VP62
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
227 if((priv->v_format==mmioFOURCC('V','P','6','1')) ||
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
228 (priv->v_format==mmioFOURCC('V','P','6','2')) ||
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
229 (priv->v_format==mmioFOURCC('V','P','3','1'))) {
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
230 stream_read(demuxer->stream,buf,10);
12277
ad3a4af318f2 More keyframe search fix for VP6x
rtognimp
parents: 12275
diff changeset
231 if (((((priv->v_format>>16) & 0xff) == '6') && ((buf[8]&0x0e)!=0x06)) ||
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
232 ((((priv->v_format>>16) & 0xff) == '3') && (buf[8]!=0x00 || buf[9]!=0x08))) {
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
233 mp_msg(MSGT_DEMUX,MSGL_V,"demux_nsv: searching %.4s keyframe...\n", (char*)&priv->v_format);
12277
ad3a4af318f2 More keyframe search fix for VP6x
rtognimp
parents: 12275
diff changeset
234 while(((((priv->v_format>>16) & 0xff) == '6') && ((buf[8]&0x0e)!=0x06)) ||
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
235 ((((priv->v_format>>16) & 0xff) == '3') && (buf[8]!=0x00 || buf[9]!=0x08))){
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
236 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %.4s block skip.\n", (char*)&priv->v_format);
12179
aeb377ccb110 Fix vp61 keyframe search (do not skip blocks if 1st frame is keyframe)
rtognimp
parents: 12175
diff changeset
237 videolen=(buf[2]>>4)|(buf[3]<<4)|(buf[4]<<0xC);
aeb377ccb110 Fix vp61 keyframe search (do not skip blocks if 1st frame is keyframe)
rtognimp
parents: 12175
diff changeset
238 audiolen=(buf[5])|(buf[6]<<8);
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
239 stream_skip(demuxer->stream, videolen+audiolen-3);
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
240 stream_read(demuxer->stream,buf,10);
12277
ad3a4af318f2 More keyframe search fix for VP6x
rtognimp
parents: 12275
diff changeset
241 if(stream_eof(demuxer->stream)) return 0;
12179
aeb377ccb110 Fix vp61 keyframe search (do not skip blocks if 1st frame is keyframe)
rtognimp
parents: 12175
diff changeset
242 if(buf[0]==0x4E){
aeb377ccb110 Fix vp61 keyframe search (do not skip blocks if 1st frame is keyframe)
rtognimp
parents: 12175
diff changeset
243 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: Got NSVs block.\n");
12272
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
244 stream_skip(demuxer->stream,7);
369073d0f143 Fix support for audio only streams
rtognimp
parents: 12198
diff changeset
245 stream_read(demuxer->stream,buf,10);
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
246 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
247 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
248 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
249
13299
6f8fe531dd73 avoid always skipping first junk with a "sync lost" message
reimar
parents: 12896
diff changeset
250 // data starts 10 bytes before current pos but later
6f8fe531dd73 avoid always skipping first junk with a "sync lost" message
reimar
parents: 12896
diff changeset
251 // we seek 17 backwards
6f8fe531dd73 avoid always skipping first junk with a "sync lost" message
reimar
parents: 12896
diff changeset
252 stream_skip(demuxer->stream,7);
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
253 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
254
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
255 switch(priv->fps){
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
256 case 0x80:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
257 sh_video->fps=30;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
258 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
259 case 0x81:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
260 sh_video->fps=(float)30000.0/1001.0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
261 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
262 case 0x82:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
263 sh_video->fps=25;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
264 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
265 case 0x83:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
266 sh_video->fps=(float)24000.0/1001.0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
267 break;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
268 case 0x85:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
269 sh_video->fps=(float)15000.0/1001.0;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
270 break;
15991
3042ee91c7dd support 10000/1001 framerate
reimar
parents: 13299
diff changeset
271 case 0x89:
3042ee91c7dd support 10000/1001 framerate
reimar
parents: 13299
diff changeset
272 sh_video->fps=(float)10000.0/1001.0;
3042ee91c7dd support 10000/1001 framerate
reimar
parents: 13299
diff changeset
273 break;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
274 default:
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
275 sh_video->fps = (float)priv->fps;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
276 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
277 sh_video->frametime = (float)1.0 / (float)sh_video->fps;
12198
759b010d6c09 Do not crash on audio only streams
rtognimp
parents: 12181
diff changeset
278 }
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
279 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
280
13299
6f8fe531dd73 avoid always skipping first junk with a "sync lost" message
reimar
parents: 12896
diff changeset
281 // seek to start of NSV header
6f8fe531dd73 avoid always skipping first junk with a "sync lost" message
reimar
parents: 12896
diff changeset
282 stream_seek(demuxer->stream,stream_tell(demuxer->stream)-17);
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
283
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
284 return demuxer;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
285 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
286
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
287 static int nsv_check_file ( demuxer_t* demuxer )
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
288 {
20473
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
289 uint32_t hdr = 0;
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
290 int i;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
291
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
292 mp_msg ( MSGT_DEMUX, MSGL_V, "Checking for Nullsoft Streaming Video\n" );
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
293
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
294 for (i = 0; i < HEADER_SEARCH_SIZE; i++) {
20473
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
295 uint8_t c = stream_read_char(demuxer->stream);
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
296 if (stream_eof(demuxer->stream))
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
297 return 0;
20473
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
298 if (hdr == mmioFOURCC('s', 'V', 'S', 'N') ||
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
299 (hdr == mmioFOURCC('f', 'V', 'S', 'N') && !c)) {
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
300 stream_seek(demuxer->stream,stream_tell(demuxer->stream)-5);
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
301 return DEMUXER_TYPE_NSV;
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
302 }
20473
6ebbcbeae8c1 Cleanup/simplify nsv check_file function.
reimar
parents: 20470
diff changeset
303 hdr = (hdr << 8) | c;
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
304 }
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
305
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
306 return 0;
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
307 }
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
308
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
309 static void demux_close_nsv(demuxer_t* demuxer) {
12175
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
310 nsv_priv_t* priv = demuxer->priv;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
311
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
312 if(!priv)
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
313 return;
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
314 free(priv);
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
315
da8e39bfe121 nsv (Nullsoft streaming video) demuxer
rtognimp
parents:
diff changeset
316 }
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
317
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
318
25707
d4fe6e23283e Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents: 22605
diff changeset
319 const demuxer_desc_t demuxer_desc_nsv = {
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
320 "NullsoftVideo demuxer",
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
321 "nsv",
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
322 "Nullsoft Streaming Video",
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
323 "Reza Jelveh",
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
324 "nsv and nsa streaming files",
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
325 DEMUXER_TYPE_NSV,
16318
e27998eeb54a Fix nsv detection with new demuxer structure
rtognimp
parents: 16175
diff changeset
326 0, // safe but expensive autodetect
16175
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
327 nsv_check_file,
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
328 demux_nsv_fill_buffer,
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
329 demux_open_nsv,
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
330 demux_close_nsv,
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
331 demux_seek_nsv,
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
332 NULL
6b86089c2edd Demuxer modularization
rtognimp
parents: 15991
diff changeset
333 };