Mercurial > mplayer.hg
comparison libmpdemux/demux_nsv.c @ 12272:369073d0f143
Fix support for audio only streams
Add keyframe search for VP62 and VP31
Based on a patch by Reza Jelveh
author | rtognimp |
---|---|
date | Sun, 25 Apr 2004 01:51:53 +0000 |
parents | 759b010d6c09 |
children | 3bd70d9bebb7 |
comparison
equal
deleted
inserted
replaced
12271:4adb4a3b52a2 | 12272:369073d0f143 |
---|---|
44 unsigned char aux[6]; | 44 unsigned char aux[6]; |
45 int i_aux = 0; | 45 int i_aux = 0; |
46 // videolen = audio chunk length, audiolen = video chunk length | 46 // videolen = audio chunk length, audiolen = video chunk length |
47 int videolen,audiolen; | 47 int videolen,audiolen; |
48 | 48 |
49 sh_video_t *sh_video = NULL; | 49 sh_video_t *sh_video = demuxer->video->sh; |
50 // sh_audio_t *sh_audio = NULL; | 50 sh_audio_t *sh_audio = demuxer->audio->sh; |
51 | 51 |
52 nsv_priv_t * priv = demuxer->priv; | 52 nsv_priv_t * priv = demuxer->priv; |
53 | |
54 sh_video = demuxer->video->sh ; | |
55 | 53 |
56 // if the audio/video chunk has no new header the first 2 bytes will be discarded 0xBEEF | 54 // if the audio/video chunk has no new header the first 2 bytes will be discarded 0xBEEF |
57 // or rather 0xEF 0xBE | 55 // or rather 0xEF 0xBE |
58 stream_read(demuxer->stream,hdr,7); | 56 stream_read(demuxer->stream,hdr,7); |
59 if(stream_eof(demuxer->stream)) return 0; | 57 if(stream_eof(demuxer->stream)) return 0; |
74 | 72 |
75 case 0xEFBE: | 73 case 0xEFBE: |
76 break; | 74 break; |
77 | 75 |
78 default: | 76 default: |
79 break; | 77 mp_dbg(MSGT_DEMUX,MSGL_WARN,"demux_nsv: sync lost\n"); |
80 } | 78 break; |
81 | 79 } |
80 | |
81 if (sh_video) | |
82 sh_video->pts = priv->v_pts =demuxer->video->pts= priv->video_pack_no * | 82 sh_video->pts = priv->v_pts =demuxer->video->pts= priv->video_pack_no * |
83 (float)sh_video->frametime; | 83 (float)sh_video->frametime; |
84 else | |
85 priv->v_pts = priv->video_pack_no; | |
84 | 86 |
85 demuxer->filepos=stream_tell(demuxer->stream); | 87 demuxer->filepos=stream_tell(demuxer->stream); |
86 | 88 |
87 | 89 |
88 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %08X: %02X %02X | %02X %02X %02X | %02X %02X \n", | 90 mp_dbg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %08X: %02X %02X | %02X %02X %02X | %02X %02X \n", |
102 } | 104 } |
103 | 105 |
104 | 106 |
105 // we need to return an empty packet when the | 107 // we need to return an empty packet when the |
106 // video frame is empty otherwise the stream will fasten up | 108 // video frame is empty otherwise the stream will fasten up |
107 if(demuxer->video){ | 109 if(sh_video) { |
108 if( (hdr[2]&0x0f) != 0x0 ) | 110 if( (hdr[2]&0x0f) != 0x0 ) |
109 ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos-i_aux,0); | 111 ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos-i_aux,0); |
110 else | 112 else |
111 ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos,0); | 113 ds_read_packet(demuxer->video,demuxer->stream,videolen,priv->v_pts,demuxer->filepos,0); |
112 } | 114 } |
115 | 117 |
116 // read audio: | 118 // read audio: |
117 audiolen=(hdr[5])|(hdr[6]<<8); | 119 audiolen=(hdr[5])|(hdr[6]<<8); |
118 // we need to return an empty packet when the | 120 // we need to return an empty packet when the |
119 // audio frame is empty otherwise the stream will fasten up | 121 // audio frame is empty otherwise the stream will fasten up |
120 if(demuxer->audio){ | 122 if(sh_audio) { |
121 ds_read_packet(demuxer->audio,demuxer->stream,audiolen,priv->v_pts,demuxer->filepos+videolen,0); | 123 ds_read_packet(demuxer->audio,demuxer->stream,audiolen,priv->v_pts,demuxer->filepos+videolen,0); |
122 } | 124 } |
123 else | 125 else |
124 stream_skip(demuxer->stream,audiolen); | 126 stream_skip(demuxer->stream,audiolen); |
125 | 127 |
133 demuxer_t* demux_open_nsv ( demuxer_t* demuxer ) | 135 demuxer_t* demux_open_nsv ( demuxer_t* demuxer ) |
134 { | 136 { |
135 // last 2 bytes 17 and 18 are unknown but right after that comes the length | 137 // last 2 bytes 17 and 18 are unknown but right after that comes the length |
136 unsigned char hdr[17]; | 138 unsigned char hdr[17]; |
137 int videolen,audiolen; | 139 int videolen,audiolen; |
138 unsigned char buf[9]; | 140 unsigned char buf[10]; |
139 sh_video_t *sh_video = NULL; | 141 sh_video_t *sh_video = NULL; |
140 sh_audio_t *sh_audio = NULL; | 142 sh_audio_t *sh_audio = NULL; |
141 | 143 |
142 | 144 |
143 nsv_priv_t * priv = malloc(sizeof(nsv_priv_t)); | 145 nsv_priv_t * priv = malloc(sizeof(nsv_priv_t)); |
254 sh_video->bih->biWidth=hdr[12]|(hdr[13]<<8); | 256 sh_video->bih->biWidth=hdr[12]|(hdr[13]<<8); |
255 sh_video->bih->biHeight=hdr[14]|(hdr[15]<<8); | 257 sh_video->bih->biHeight=hdr[14]|(hdr[15]<<8); |
256 memcpy(&sh_video->bih->biCompression,hdr+4,4); | 258 memcpy(&sh_video->bih->biCompression,hdr+4,4); |
257 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3; | 259 sh_video->bih->biSizeImage=sh_video->bih->biWidth*sh_video->bih->biHeight*3; |
258 | 260 |
259 // !!!!!!!!!!!!!!!!!!!! | |
260 // RemoveMe!!! This is just to avoid lot of bugreports! | |
261 // !!!!!!!!!!!!!!!!!!!! | |
262 if(priv->v_format==mmioFOURCC('V','P','5','0')) | |
263 mp_msg(MSGT_DEMUX,MSGL_WARN,"demux_nsv: VP50 video does not work yet. Expect problems.\n"); | |
264 | |
265 // here we search for the correct keyframe | 261 // here we search for the correct keyframe |
266 // vp6 keyframe is when the 2nd byte of the vp6 header is 0x36 | 262 // vp6 keyframe is when the 2nd byte of the vp6 header is 0x36 |
267 if(priv->v_format==mmioFOURCC('V','P','6','1')){ | 263 if((priv->v_format==mmioFOURCC('V','P','6','1')) || |
268 stream_read(demuxer->stream,buf,9); | 264 (priv->v_format==mmioFOURCC('V','P','6','2')) || |
269 if (hdr[8]!=0x36) { | 265 (priv->v_format==mmioFOURCC('V','P','3','1'))) { |
270 mp_msg(MSGT_DEMUX,MSGL_V,"demux_nsv: searching vp6 keyframe...\n"); | 266 stream_read(demuxer->stream,buf,10); |
271 while(buf[8]!=0x36){ | 267 if (((((priv->v_format>>16) & 0xff) == '6') && (buf[8]!=0x36)) || |
272 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: vp6 block skip.\n"); | 268 ((((priv->v_format>>16) & 0xff) == '3') && (buf[8]!=0x00 || buf[9]!=0x08))) { |
269 mp_msg(MSGT_DEMUX,MSGL_V,"demux_nsv: searching %.4s keyframe...\n", (char*)&priv->v_format); | |
270 while(((((priv->v_format>>16) & 0xff) == '6') && (buf[8]!=0x36)) || | |
271 ((((priv->v_format>>16) & 0xff) == '3') && (buf[8]!=0x00 || buf[9]!=0x08))){ | |
272 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: %.4s block skip.\n", (char*)&priv->v_format); | |
273 videolen=(buf[2]>>4)|(buf[3]<<4)|(buf[4]<<0xC); | 273 videolen=(buf[2]>>4)|(buf[3]<<4)|(buf[4]<<0xC); |
274 audiolen=(buf[5])|(buf[6]<<8); | 274 audiolen=(buf[5])|(buf[6]<<8); |
275 stream_skip(demuxer->stream, videolen+audiolen-2); | 275 stream_skip(demuxer->stream, videolen+audiolen-3); |
276 stream_read(demuxer->stream,buf,9); | 276 stream_read(demuxer->stream,buf,10); |
277 if(buf[0]==0x4E){ | 277 if(buf[0]==0x4E){ |
278 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: Got NSVs block.\n"); | 278 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_nsv: Got NSVs block.\n"); |
279 if(stream_eof(demuxer->stream)) return 0; | 279 if(stream_eof(demuxer->stream)) return 0; |
280 stream_skip(demuxer->stream,8); | 280 stream_skip(demuxer->stream,7); |
281 stream_read(demuxer->stream,buf,9); | 281 stream_read(demuxer->stream,buf,10); |
282 } | 282 } |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 | 286 |
287 stream_seek(demuxer->stream,stream_tell(demuxer->stream)-9); | 287 stream_seek(demuxer->stream,stream_tell(demuxer->stream)-10); |
288 } | 288 } |
289 | |
290 | 289 |
291 switch(priv->fps){ | 290 switch(priv->fps){ |
292 case 0x80: | 291 case 0x80: |
293 sh_video->fps=30; | 292 sh_video->fps=30; |
294 break; | 293 break; |