ao_pulse: support native mute control
[mplayer.git] / libmpdemux / video.c
blob2e41cf0b4b66b1e21fa79219ee491384c8ca148f
1 /*
2 * video frame reading
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "config.h"
23 #include <stdio.h>
24 #if HAVE_MALLOC_H
25 #include <malloc.h>
26 #endif
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
31 #include "mp_msg.h"
33 #include "stream/stream.h"
34 #include "demuxer.h"
35 #ifdef DEMUX_TY_OSD
36 #include "demux_ty_osd.h"
37 #endif
38 #include "stheader.h"
39 #include "parse_es.h"
40 #include "mpeg_hdr.h"
42 /* sub_cc (closed captions)*/
43 #include "sub/sub_cc.h"
45 /* biCompression constant */
46 #define BI_RGB 0L
48 #ifdef CONFIG_LIVE555
49 #include "demux_rtp.h"
50 #endif
52 static mp_mpeg_header_t picture;
54 static int telecine=0;
55 static float telecine_cnt=-2.5;
57 typedef enum {
58 VIDEO_MPEG12,
59 VIDEO_MPEG4,
60 VIDEO_H264,
61 VIDEO_VC1,
62 VIDEO_OTHER
63 } video_codec_t;
65 static video_codec_t find_video_codec(sh_video_t *sh_video)
67 demux_stream_t *d_video=sh_video->ds;
68 int fmt = d_video->demuxer->file_format;
70 if(
71 (fmt == DEMUXER_TYPE_PVA) ||
72 (fmt == DEMUXER_TYPE_MPEG_ES) ||
73 (fmt == DEMUXER_TYPE_MPEG_GXF) ||
74 (fmt == DEMUXER_TYPE_MPEG_PES) ||
76 (fmt == DEMUXER_TYPE_MPEG_PS || fmt == DEMUXER_TYPE_MPEG_TS) &&
77 ((! sh_video->format) || (sh_video->format==0x10000001) || (sh_video->format==0x10000002))
78 ) ||
79 (fmt == DEMUXER_TYPE_MPEG_TY)
80 #ifdef CONFIG_LIVE555
81 || ((fmt == DEMUXER_TYPE_RTP) && demux_is_mpeg_rtp_stream(d_video->demuxer))
82 #endif
84 return VIDEO_MPEG12;
85 else if((fmt == DEMUXER_TYPE_MPEG4_ES) ||
86 ((fmt == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000004)) ||
87 ((fmt == DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000004))
89 return VIDEO_MPEG4;
90 else if((fmt == DEMUXER_TYPE_H264_ES) ||
91 ((fmt == DEMUXER_TYPE_MPEG_TS) && (sh_video->format==0x10000005)) ||
92 ((fmt == DEMUXER_TYPE_MPEG_PS) && (sh_video->format==0x10000005))
94 return VIDEO_H264;
95 else if((fmt == DEMUXER_TYPE_MPEG_PS || fmt == DEMUXER_TYPE_MPEG_TS) &&
96 (sh_video->format==mmioFOURCC('W', 'V', 'C', '1')))
97 return VIDEO_VC1;
98 else if (fmt == DEMUXER_TYPE_ASF && sh_video->bih && sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' '))
99 return VIDEO_MPEG12;
100 else
101 return VIDEO_OTHER;
104 int video_read_properties(sh_video_t *sh_video){
105 demux_stream_t *d_video=sh_video->ds;
106 video_codec_t video_codec = find_video_codec(sh_video);
107 // Determine image properties:
108 switch(video_codec){
109 case VIDEO_OTHER: {
110 if((d_video->demuxer->file_format == DEMUXER_TYPE_ASF) || (d_video->demuxer->file_format == DEMUXER_TYPE_AVI)) {
111 // display info:
112 // in case no strf chunk has been seen in avi, we have no bitmap header
113 if(!sh_video->bih) return 0;
114 sh_video->format=sh_video->bih->biCompression;
115 sh_video->disp_w=sh_video->bih->biWidth;
116 sh_video->disp_h=abs(sh_video->bih->biHeight);
118 break;
120 case VIDEO_MPEG4: {
121 int pos = 0, vop_cnt=0, units[3];
122 videobuf_len=0; videobuf_code_len=0;
123 mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for Video Object Start code... ");
124 while(1){
125 int i=sync_video_packet(d_video);
126 if(i<=0x11F) break; // found it!
127 if(!i || !skip_video_packet(d_video)){
128 mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
129 return 0;
132 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
133 if(!videobuffer) {
134 videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
135 if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
136 else {
137 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
138 return 0;
141 mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for Video Object Layer Start code... ");
142 while(1){
143 int i=sync_video_packet(d_video);
144 mp_msg(MSGT_DECVIDEO,MSGL_V,"M4V: 0x%X\n",i);
145 if(i>=0x120 && i<=0x12F) break; // found it!
146 if(!i || !read_video_packet(d_video)){
147 mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
148 return 0;
151 pos = videobuf_len+4;
152 if(!read_video_packet(d_video)){
153 mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read Video Object Layer Header\n");
154 return 0;
156 mp4_header_process_vol(&picture, &(videobuffer[pos]));
157 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK! FPS SEEMS TO BE %.3f\nSearching for Video Object Plane Start code... ", sh_video->fps);
158 mp4_init:
159 while(1){
160 int i=sync_video_packet(d_video);
161 if(i==0x1B6) break; // found it!
162 if(!i || !read_video_packet(d_video)){
163 mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
164 return 0;
167 pos = videobuf_len+4;
168 if(!read_video_packet(d_video)){
169 mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read Video Object Plane Header\n");
170 return 0;
172 mp4_header_process_vop(&picture, &(videobuffer[pos]));
173 sh_video->disp_w = picture.display_picture_width;
174 sh_video->disp_h = picture.display_picture_height;
175 units[vop_cnt] = picture.timeinc_unit;
176 vop_cnt++;
177 //mp_msg(MSGT_DECVIDEO,MSGL_V, "TYPE: %d, unit: %d\n", picture.picture_type, picture.timeinc_unit);
178 if(!picture.fps) {
179 int i, mn, md, mx, diff;
180 if(vop_cnt < 3)
181 goto mp4_init;
183 i=0;
184 mn = mx = units[0];
185 for(i=0; i<3; i++) {
186 if(units[i] < mn)
187 mn = units[i];
188 if(units[i] > mx)
189 mx = units[i];
191 md = mn;
192 for(i=0; i<3; i++) {
193 if((units[i] > mn) && (units[i] < mx))
194 md = units[i];
196 mp_msg(MSGT_DECVIDEO,MSGL_V, "MIN: %d, mid: %d, max: %d\n", mn, md, mx);
197 if(mx - md > md - mn)
198 diff = md - mn;
199 else
200 diff = mx - md;
201 if(diff > 0){
202 picture.fps = ((float)picture.timeinc_resolution) / diff;
203 mp_msg(MSGT_DECVIDEO,MSGL_V, "FPS seems to be: %f, resolution: %d, delta_units: %d\n", picture.fps, picture.timeinc_resolution, diff);
206 if(picture.fps) {
207 sh_video->fps=picture.fps;
208 sh_video->frametime=1.0/picture.fps;
209 mp_msg(MSGT_DECVIDEO,MSGL_INFO, "FPS seems to be: %f\n", picture.fps);
211 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
212 sh_video->format=0x10000004;
213 break;
215 case VIDEO_H264: {
216 int pos = 0;
217 videobuf_len=0; videobuf_code_len=0;
218 mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence parameter set... ");
219 while(1){
220 int i=sync_video_packet(d_video);
221 if((i&~0x60) == 0x107 && i != 0x107) break; // found it!
222 if(!i || !skip_video_packet(d_video)){
223 mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
224 return 0;
227 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
228 if(!videobuffer) {
229 videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
230 if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
231 else {
232 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
233 return 0;
236 pos = videobuf_len+4;
237 if(!read_video_packet(d_video)){
238 mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Can't read sequence parameter set\n");
239 return 0;
241 h264_parse_sps(&picture, &(videobuffer[pos]), videobuf_len - pos);
242 sh_video->disp_w=picture.display_picture_width;
243 sh_video->disp_h=picture.display_picture_height;
244 mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for picture parameter set... ");
245 while(1){
246 int i=sync_video_packet(d_video);
247 mp_msg(MSGT_DECVIDEO,MSGL_V,"H264: 0x%X\n",i);
248 if((i&~0x60) == 0x108 && i != 0x108) break; // found it!
249 if(!i || !read_video_packet(d_video)){
250 mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
251 return 0;
254 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\nSearching for Slice... ");
255 while(1){
256 int i=sync_video_packet(d_video);
257 if((i&~0x60) == 0x101 || (i&~0x60) == 0x102 || (i&~0x60) == 0x105) break; // found it!
258 if(!i || !read_video_packet(d_video)){
259 mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
260 return 0;
263 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
264 sh_video->format=0x10000005;
265 if(picture.fps) {
266 sh_video->fps=picture.fps;
267 sh_video->frametime=1.0/picture.fps;
268 mp_msg(MSGT_DECVIDEO,MSGL_INFO, "FPS seems to be: %f\n", picture.fps);
270 break;
272 case VIDEO_MPEG12: {
273 if (d_video->demuxer->file_format == DEMUXER_TYPE_ASF) { // DVR-MS
274 if(!sh_video->bih) return 0;
275 sh_video->format=sh_video->bih->biCompression;
277 mpeg_header_parser:
278 // Find sequence_header first:
279 videobuf_len=0; videobuf_code_len=0;
280 telecine=0; telecine_cnt=-2.5;
281 mp_msg(MSGT_DECVIDEO,MSGL_V,"Searching for sequence header... ");
282 while(1){
283 int i=sync_video_packet(d_video);
284 if(i==0x1B3) break; // found it!
285 if(!i || !skip_video_packet(d_video)){
286 if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
287 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"MPEG: FATAL: EOF while searching for sequence header.\n");
288 return 0;
291 mp_msg(MSGT_DECVIDEO,MSGL_V,"OK!\n");
292 // ========= Read & process sequence header & extension ============
293 if(!videobuffer) {
294 videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
295 if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
296 else {
297 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
298 return 0;
302 if(!read_video_packet(d_video)){
303 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"FATAL: Cannot read sequence header.\n");
304 return 0;
306 if(mp_header_process_sequence_header (&picture, &videobuffer[4])) {
307 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"MPEG: bad sequence header\n");
308 goto mpeg_header_parser;
310 if(sync_video_packet(d_video)==0x1B5){ // next packet is seq. ext.
311 int pos=videobuf_len;
312 if(!read_video_packet(d_video)){
313 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"FATAL: Cannot read sequence header extension.\n");
314 return 0;
316 if(mp_header_process_extension (&picture, &videobuffer[pos+4])) {
317 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"MPEG: bad sequence header extension\n");
318 return 0;
322 // display info:
323 sh_video->format=picture.mpeg1?0x10000001:0x10000002; // mpeg video
324 sh_video->fps=picture.fps * picture.frame_rate_extension_n / picture.frame_rate_extension_d;
325 if(!sh_video->fps){
326 sh_video->frametime=0;
327 } else {
328 sh_video->frametime=1.0/sh_video->fps;
330 sh_video->disp_w=picture.display_picture_width;
331 sh_video->disp_h=picture.display_picture_height;
332 // bitrate:
333 if(picture.bitrate!=0x3FFFF) // unspecified/VBR ?
334 sh_video->i_bps=picture.bitrate * 400 / 8;
335 // info:
336 mp_dbg(MSGT_DECVIDEO,MSGL_DBG2,"mpeg bitrate: %d (%X)\n",picture.bitrate,picture.bitrate);
337 mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: %s %dx%d (aspect %d) %5.3f fps %5.1f kbps (%4.1f kbyte/s)\n",
338 picture.mpeg1?"MPEG1":"MPEG2",
339 sh_video->disp_w,sh_video->disp_h,
340 picture.aspect_ratio_information,
341 sh_video->fps,
342 sh_video->i_bps * 8 / 1000.0,
343 sh_video->i_bps / 1000.0 );
344 break;
346 case VIDEO_VC1: {
347 // Find sequence_header:
348 videobuf_len=0;
349 videobuf_code_len=0;
350 mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Searching for VC1 sequence header... ");
351 while(1){
352 int i=sync_video_packet(d_video);
353 if(i==0x10F) break; // found it!
354 if(!i || !skip_video_packet(d_video)){
355 if( mp_msg_test(MSGT_DECVIDEO,MSGL_V) ) mp_msg(MSGT_DECVIDEO,MSGL_V,"NONE :(\n");
356 mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Couldn't find VC-1 sequence header\n");
357 return 0;
360 mp_msg(MSGT_DECVIDEO,MSGL_INFO,"found\n");
361 if(!videobuffer) {
362 videobuffer = memalign(8, VIDEOBUFFER_SIZE + MP_INPUT_BUFFER_PADDING_SIZE);
363 if (videobuffer) memset(videobuffer+VIDEOBUFFER_SIZE, 0, MP_INPUT_BUFFER_PADDING_SIZE);
364 else {
365 mp_tmsg(MSGT_DECVIDEO,MSGL_ERR,"Cannot allocate shared memory.\n");
366 return 0;
369 if(!read_video_packet(d_video)){
370 mp_msg(MSGT_DECVIDEO,MSGL_ERR, "Couldn't read VC-1 sequence header!\n");
371 return 0;
374 while(1) {
375 int i=sync_video_packet(d_video);
376 if(i==0x10E) break; // found it!
377 if(!i || !skip_video_packet(d_video)){
378 mp_msg(MSGT_DECVIDEO,MSGL_V,"Couldn't find VC-1 entry point sync-code:(\n");
379 return 0;
382 if(!read_video_packet(d_video)){
383 mp_msg(MSGT_DECVIDEO,MSGL_V,"Couldn't read VC-1 entry point sync-code:(\n");
384 return 0;
387 if(mp_vc1_decode_sequence_header(&picture, &videobuffer[4], videobuf_len-4)) {
388 sh_video->bih = calloc(1, sizeof(*sh_video->bih) + videobuf_len);
389 if(sh_video->bih == NULL) {
390 mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Couldn't alloc %zu bytes for VC-1 extradata!\n", sizeof(*sh_video->bih) + videobuf_len);
391 return 0;
393 sh_video->bih->biSize= sizeof(*sh_video->bih) + videobuf_len;
394 memcpy(sh_video->bih + 1, videobuffer, videobuf_len);
395 sh_video->bih->biCompression = sh_video->format;
396 sh_video->bih->biWidth = sh_video->disp_w = picture.display_picture_width;
397 sh_video->bih->biHeight = sh_video->disp_h = picture.display_picture_height;
398 if(picture.fps > 0) {
399 sh_video->frametime=1.0/picture.fps;
400 sh_video->fps = picture.fps;
402 mp_msg(MSGT_DECVIDEO,MSGL_INFO,"VIDEO: VC-1 %dx%d, %5.3f fps, header len: %d\n",
403 sh_video->disp_w, sh_video->disp_h, sh_video->fps, videobuf_len);
405 break;
407 } // switch(file_format)
409 return 1;
412 static void process_userdata(const unsigned char* buf,int len){
413 int i;
414 /* if the user data starts with "CC", assume it is a CC info packet */
415 if(len>2 && buf[0]=='C' && buf[1]=='C'){
416 // mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"video.c: process_userdata() detected Closed Captions!\n");
417 subcc_process_data(buf+2,len-2);
419 #ifdef DEMUX_TY_OSD
420 if( len > 2 && buf[ 0 ] == 'T' && buf[ 1 ] == 'Y' )
422 ty_processuserdata( buf + 2, len - 2 );
423 return;
425 #endif
426 if(verbose<2) return;
427 fprintf(stderr, "user_data: len=%3d %02X %02X %02X %02X '",
428 len, buf[0], buf[1], buf[2], buf[3]);
429 for(i=0;i<len;i++)
430 // if(buf[i]>=32 && buf[i]<127) fputc(buf[i], stderr);
431 if(buf[i]&0x60) fputc(buf[i]&0x7F, stderr);
432 fprintf(stderr, "'\n");
435 int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char** start,int force_fps){
436 demux_stream_t *d_video=sh_video->ds;
437 demuxer_t *demuxer=d_video->demuxer;
438 float frame_time=1;
439 float pts1=d_video->pts;
440 float pts=0;
441 float fps;
442 int picture_coding_type=0;
443 int in_size=0;
444 video_codec_t video_codec = find_video_codec(sh_video);
446 *start=NULL;
448 if(video_codec == VIDEO_MPEG12){
449 int in_frame=0;
450 //float newfps;
451 //videobuf_len=0;
452 while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
453 int i=sync_video_packet(d_video);
454 //void* buffer=&videobuffer[videobuf_len+4];
455 int start=videobuf_len+4;
456 if(in_frame){
457 if(i<0x101 || i>=0x1B0){ // not slice code -> end of frame
458 if(!i) return -1; // EOF
459 break;
461 } else {
462 if(i==0x100){
463 pts=d_video->pts;
464 d_video->pts=0;
466 if(i>=0x101 && i<0x1B0) in_frame=1; // picture startcode
467 else if(!i) return -1; // EOF
469 if(!read_video_packet(d_video)) return -1; // EOF
470 // process headers:
471 switch(i){
472 case 0x1B3: mp_header_process_sequence_header (&picture, &videobuffer[start]);break;
473 case 0x1B5: mp_header_process_extension (&picture, &videobuffer[start]);break;
474 case 0x1B2: process_userdata (&videobuffer[start], videobuf_len-start);break;
475 case 0x100: picture_coding_type=(videobuffer[start+1] >> 3) & 7;break;
478 fps = picture.fps * picture.frame_rate_extension_n / picture.frame_rate_extension_d;
480 *start=videobuffer; in_size=videobuf_len;
482 // get mpeg fps:
483 if(sh_video->fps!=fps) if(!force_fps && !telecine){
484 mp_msg(MSGT_CPLAYER,MSGL_WARN,"Warning! FPS changed %5.3f -> %5.3f (%f) [%d] \n",sh_video->fps,fps,sh_video->fps-fps,picture.frame_rate_code);
485 sh_video->fps=fps;
486 sh_video->frametime=1.0/fps;
489 // fix mpeg2 frametime:
490 frame_time=(picture.display_time)*0.01f;
491 picture.display_time=100;
492 videobuf_len=0;
494 telecine_cnt*=0.9; // drift out error
495 telecine_cnt+=frame_time-5.0/4.0;
496 mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"\r telecine = %3.1f %5.3f \n",frame_time,telecine_cnt);
498 if(telecine){
499 frame_time=1;
500 if(telecine_cnt<-1.5 || telecine_cnt>1.5){
501 mp_tmsg(MSGT_DECVIDEO,MSGL_INFO,"\ndemux_mpg: 30000/1001fps NTSC content detected, switching framerate.\n");
502 telecine=0;
504 } else
505 if(telecine_cnt>-0.5 && telecine_cnt<0.5 && !force_fps){
506 sh_video->fps=sh_video->fps*4/5;
507 sh_video->frametime=sh_video->frametime*5/4;
508 mp_tmsg(MSGT_DECVIDEO,MSGL_INFO,"\ndemux_mpg: 24000/1001fps progressive NTSC content detected, switching framerate.\n");
509 telecine=1;
511 } else if(video_codec == VIDEO_MPEG4){
512 while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
513 int i=sync_video_packet(d_video);
514 if(!i) return -1;
515 if(!read_video_packet(d_video)) return -1; // EOF
516 if(i==0x1B6) break;
518 *start=videobuffer; in_size=videobuf_len;
519 videobuf_len=0;
520 } else if(video_codec == VIDEO_H264){
521 int in_picture = 0;
522 while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE){
523 int i=sync_video_packet(d_video);
524 int pos = videobuf_len+4;
525 if(!i) return -1;
526 if(!read_video_packet(d_video)) return -1; // EOF
527 if((i&~0x60) == 0x107 && i != 0x107) {
528 h264_parse_sps(&picture, &(videobuffer[pos]), videobuf_len - pos);
529 if(picture.fps > 0) {
530 sh_video->fps=picture.fps;
531 sh_video->frametime=1.0/picture.fps;
533 i=sync_video_packet(d_video);
534 if(!i) return -1;
535 if(!read_video_packet(d_video)) return -1; // EOF
538 // here starts the access unit end detection code
539 // see the mail on MPlayer-dev-eng for details:
540 // Date: Sat, 17 Sep 2005 11:24:06 +0200
541 // Subject: Re: [MPlayer-dev-eng] [RFC] h264 ES parser problems
542 // Message-ID: <20050917092406.GA7699@rz.uni-karlsruhe.de>
543 if((i&~0x60) == 0x101 || (i&~0x60) == 0x102 || (i&~0x60) == 0x105)
544 // found VCL NAL with slice header i.e. start of current primary coded
545 // picture, so start scanning for the end now
546 in_picture = 1;
547 if (in_picture) {
548 i = sync_video_packet(d_video) & ~0x60; // code of next packet
549 if(i == 0x106 || i == 0x109) break; // SEI or access unit delim.
550 if(i == 0x101 || i == 0x102 || i == 0x105) {
551 // assuming arbitrary slice ordering is not allowed, the
552 // first_mb_in_slice (golomb encoded) value should be 0 then
553 // for the first VCL NAL in a picture
554 if (demux_peekc(d_video) & 0x80)
555 break;
559 *start=videobuffer; in_size=videobuf_len;
560 videobuf_len=0;
561 } else if(video_codec == VIDEO_VC1) {
562 while(videobuf_len<VIDEOBUFFER_SIZE-MAX_VIDEO_PACKET_SIZE) {
563 int i=sync_video_packet(d_video);
564 if(!i) return -1;
565 if(!read_video_packet(d_video)) return -1; // EOF
566 if(i==0x10D) break;
568 *start=videobuffer;
569 in_size=videobuf_len;
570 videobuf_len=0;
571 } else {
572 // frame-based file formats: (AVI,ASF,MOV)
573 in_size=ds_get_packet(d_video,start);
574 if(in_size<0) return -1; // EOF
578 //------------------------ frame decoded. --------------------
580 // Increase video timers:
581 sh_video->num_frames+=frame_time;
582 ++sh_video->num_frames_decoded;
584 frame_time*=sh_video->frametime;
586 // override frame_time for variable/unknown FPS formats:
587 if(!force_fps) switch(demuxer->file_format){
588 case DEMUXER_TYPE_GIF:
589 case DEMUXER_TYPE_MATROSKA:
590 case DEMUXER_TYPE_MNG:
591 if(d_video->pts>0 && pts1>0 && d_video->pts>pts1)
592 frame_time=d_video->pts-pts1;
593 break;
594 case DEMUXER_TYPE_TV:
595 case DEMUXER_TYPE_MOV:
596 case DEMUXER_TYPE_FILM:
597 case DEMUXER_TYPE_VIVO:
598 case DEMUXER_TYPE_OGG:
599 case DEMUXER_TYPE_ASF: {
600 double next_pts = ds_get_next_pts(d_video);
601 double d= (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts-pts1;
602 if(d>=0){
603 if(d>0){
604 if((int)sh_video->fps==1000)
605 mp_msg(MSGT_CPLAYER,MSGL_V,"\navg. framerate: %d fps \n",(int)(1.0f/d));
606 sh_video->frametime=d; // 1ms
607 sh_video->fps=1.0f/d;
609 frame_time = d;
610 } else {
611 mp_msg(MSGT_CPLAYER,MSGL_WARN,"\nInvalid frame duration value (%5.3f/%5.3f => %5.3f). Defaulting to %5.3f sec.\n",d_video->pts,next_pts,d,frame_time);
612 // frame_time = 1/25.0;
615 break;
616 case DEMUXER_TYPE_LAVF:
617 case DEMUXER_TYPE_LAVF_PREFERRED:
618 if((int)sh_video->fps==1000 || (int)sh_video->fps<=1){
619 double next_pts = ds_get_next_pts(d_video);
620 double d= (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts-pts1;
621 if(d>=0){
622 frame_time = d;
625 break;
626 case DEMUXER_TYPE_REAL:
628 double next_pts = ds_get_next_pts(d_video);
629 double d = (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts - pts1;
631 frame_time = (d >= 0 && pts1 > 0) ? d : 0.001;
633 break;
636 if(video_codec == VIDEO_MPEG12){
637 sh_video->pts+=frame_time;
638 if(picture_coding_type==1)
639 d_video->flags |= 1;
640 if(picture_coding_type<=2 && sh_video->i_pts){
641 sh_video->pts=sh_video->i_pts;
642 sh_video->i_pts=pts;
643 } else {
644 if(pts){
645 if(picture_coding_type<=2) sh_video->i_pts=pts;
646 else sh_video->pts=pts;
649 } else
650 sh_video->pts=d_video->pts;
652 if(frame_time_ptr) *frame_time_ptr=frame_time;
653 return in_size;