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;