fbui | Framebuffer-based graphical environment |
| download: https://git.y1.nz/archives/fbui.tar.gz | |
| README | Files | Log | Refs |
libfbui/MPEG/mpeg2dec.c
1
2 /* mpeg2dec.c, main(), initialization, option processing */
3
4 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
5
6 /*
7 * Disclaimer of Warranty
8 *
9 * These software programs are available to the user without any license fee or
10 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
11 * any and all warranties, whether express, implied, or statuary, including any
12 * implied warranties or merchantability or of fitness for a particular
13 * purpose. In no event shall the copyright-holder be liable for any
14 * incidental, punitive, or consequential damages of any kind whatsoever
15 * arising from the use of these programs.
16 *
17 * This disclaimer of warranty extends to the user of these programs and user's
18 * customers, employees, agents, transferees, successors, and assigns.
19 *
20 * The MPEG Software Simulation Group does not represent or warrant that the
21 * programs furnished hereunder are free of infringement of any third-party
22 * patents.
23 *
24 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
25 * are subject to royalty fees to patent holders. Many of these patents are
26 * general enough such that they are unavoidable regardless of implementation
27 * design.
28 *
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <fcntl.h>
35
36 #define GLOBAL
37 #include "config.h"
38 #include "global.h"
39
40 /* private prototypes */
41 static int video_sequence _ANSI_ARGS_((int *framenum));
42 static int Decode_Bitstream _ANSI_ARGS_((void));
43 static int Headers _ANSI_ARGS_((void));
44 static void Initialize_Sequence _ANSI_ARGS_((void));
45 static void Initialize_Decoder _ANSI_ARGS_((void));
46 static void Deinitialize_Sequence _ANSI_ARGS_((void));
47 static void Process_Options _ANSI_ARGS_((int argc, char *argv[]));
48
49 int fbui_console;
50
51 #if OLD
52 static int Get_Val _ANSI_ARGS_((char *argv[]));
53 #endif
54
55 /* #define DEBUG */
56
57 static void Clear_Options();
58 #ifdef DEBUG
59 static void Print_Options();
60 #endif
61
62 int main(argc,argv)
63 int argc;
64 char *argv[];
65 {
66 int ret, code;
67
68 Clear_Options();
69
70 fbui_console = -1;
71
72 /* decode command line arguments */
73 Process_Options(argc,argv);
74
75 #ifdef DEBUG
76 Print_Options();
77 #endif
78
79 ld = &base; /* select base layer context */
80
81 /* open MPEG base layer bitstream file(s) */
82 /* NOTE: this is either a base layer stream or a spatial enhancement stream */
83 if ((base.Infile=open(Main_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
84 {
85 fprintf(stderr,"Base layer input file %s not found\n", Main_Bitstream_Filename);
86 exit(1);
87 }
88
89
90 if(base.Infile != 0)
91 {
92 Initialize_Buffer();
93
94 if(Show_Bits(8)==0x47)
95 {
96 sprintf(Error_Text,"Decoder currently does not parse transport streams\n");
97 Error(Error_Text);
98 }
99
100 next_start_code();
101 code = Show_Bits(32);
102
103 switch(code)
104 {
105 case SEQUENCE_HEADER_CODE:
106 break;
107 case PACK_START_CODE:
108 System_Stream_Flag = 1;
109 case VIDEO_ELEMENTARY_STREAM:
110 System_Stream_Flag = 1;
111 break;
112 default:
113 sprintf(Error_Text,"Unable to recognize stream type\n");
114 Error(Error_Text);
115 break;
116 }
117
118 lseek(base.Infile, 0l, 0);
119 Initialize_Buffer();
120 }
121
122 if(base.Infile!=0)
123 {
124 lseek(base.Infile, 0l, 0);
125 }
126
127 Initialize_Buffer();
128
129 if(Two_Streams)
130 {
131 ld = &enhan; /* select enhancement layer context */
132
133 if ((enhan.Infile = open(Enhancement_Layer_Bitstream_Filename,O_RDONLY|O_BINARY))<0)
134 {
135 sprintf(Error_Text,"enhancment layer bitstream file %s not found\n",
136 Enhancement_Layer_Bitstream_Filename);
137
138 Error(Error_Text);
139 }
140
141 Initialize_Buffer();
142 ld = &base;
143 }
144
145 Initialize_Decoder();
146
147 ret = Decode_Bitstream();
148
149 close(base.Infile);
150
151 if (Two_Streams)
152 close(enhan.Infile);
153
154 return 0;
155 }
156
157 /* IMPLEMENTAION specific rouintes */
158 static void Initialize_Decoder()
159 {
160 int i;
161
162 /* Clip table */
163 if (!(Clip=(unsigned char *)malloc(1024)))
164 Error("Clip[] malloc failed\n");
165
166 Clip += 384;
167
168 for (i=-384; i<640; i++)
169 Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i);
170
171 /* IDCT */
172 if (Reference_IDCT_Flag)
173 Initialize_Reference_IDCT();
174 else
175 Initialize_Fast_IDCT();
176
177 }
178
179 /* mostly IMPLEMENTAION specific rouintes */
180 static void Initialize_Sequence()
181 {
182 int cc, size;
183 static int Table_6_20[3] = {6,8,12};
184
185 /* check scalability mode of enhancement layer */
186 if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP))
187 Error("unsupported scalability mode\n");
188
189 /* force MPEG-1 parameters for proper decoder behavior */
190 /* see ISO/IEC 13818-2 section D.9.14 */
191 if (!base.MPEG2_Flag)
192 {
193 progressive_sequence = 1;
194 progressive_frame = 1;
195 picture_structure = FRAME_PICTURE;
196 frame_pred_frame_dct = 1;
197 chroma_format = CHROMA420;
198 matrix_coefficients = 5;
199 }
200
201 /* round to nearest multiple of coded macroblocks */
202 /* ISO/IEC 13818-2 section 6.3.3 sequence_header() */
203 mb_width = (horizontal_size+15)/16;
204 mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32)
205 : (vertical_size+15)/16;
206
207 Coded_Picture_Width = 16*mb_width;
208 Coded_Picture_Height = 16*mb_height;
209
210 /* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */
211 Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width
212 : Coded_Picture_Width>>1;
213 Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height
214 : Coded_Picture_Height>>1;
215
216 /* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */
217 block_count = Table_6_20[chroma_format-1];
218
219 for (cc=0; cc<3; cc++)
220 {
221 if (cc==0)
222 size = Coded_Picture_Width*Coded_Picture_Height;
223 else
224 size = Chroma_Width*Chroma_Height;
225
226 if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size)))
227 Error("backward_reference_frame[] malloc failed\n");
228
229 if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size)))
230 Error("forward_reference_frame[] malloc failed\n");
231
232 if (!(auxframe[cc] = (unsigned char *)malloc(size)))
233 Error("auxframe[] malloc failed\n");
234
235 if(Ersatz_Flag)
236 if (!(substitute_frame[cc] = (unsigned char *)malloc(size)))
237 Error("substitute_frame[] malloc failed\n");
238
239
240 if (base.scalable_mode==SC_SPAT)
241 {
242 /* this assumes lower layer is 4:2:0 */
243 if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
244 Error("llframe0 malloc failed\n");
245 if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1))))
246 Error("llframe1 malloc failed\n");
247 }
248 }
249
250 /* SCALABILITY: Spatial */
251 if (base.scalable_mode==SC_SPAT)
252 {
253 if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short))))
254 Error("lltmp malloc failed\n");
255 }
256
257 #ifdef DISPLAY
258 if (Output_Type==T_X11)
259 {
260 Initialize_Display_Process("");
261 Initialize_Dither_Matrix();
262 }
263 #endif /* DISPLAY */
264
265 }
266
267 void Error(text)
268 char *text;
269 {
270 fprintf(stderr,text);
271 exit(1);
272 }
273
274 /* Trace_Flag output */
275 void Print_Bits(code,bits,len)
276 int code,bits,len;
277 {
278 int i;
279 for (i=0; i<len; i++)
280 printf("%d",(code>>(bits-1-i))&1);
281 }
282
283
284 /* option processing */
285 static void Process_Options(argc,argv)
286 int argc; /* argument count */
287 char *argv[]; /* argument vector */
288 {
289 int i, LastArg, NextArg;
290
291 /* at least one argument should be present */
292 if (argc<2)
293 {
294 printf("\n%s, %s\n",Version,Author);
295 printf("Usage: mpeg2decode {options}\n\
296 Options: -b file main bitstream (base or spatial enhancement layer)\n\
297 -# FBUI console number\n\
298 -cn file conformance report (n: level)\n\
299 -e file enhancement layer bitstream (SNR or Data Partitioning)\n\
300 -f store/display interlaced video in frame format\n\
301 -g concatenated file format for substitution method (-x)\n\
302 -in file information & statistics report (n: level)\n\
303 -l file file name pattern for lower layer sequence\n\
304 (for spatial scalability)\n\
305 -on file output format (0:YUV 1:SIF 2:TGA 3:PPM 4:X11 5:X11HiQ 6:FBUI)\n\
306 -q disable warnings to stderr\n\
307 -r use double precision reference IDCT\n\
308 -t enable low level tracing to stdout\n\
309 -u file print user_data to stdio or file\n\
310 -vn verbose output (n: level)\n\
311 -x file filename pattern of picture substitution sequence\n\n\
312 File patterns: for sequential filenames, \"printf\" style, e.g. rec%%d\n\
313 or rec%%d%%c for fieldwise storage\n\
314 Levels: 0:none 1:sequence 2:picture 3:slice 4:macroblock 5:block\n\n\
315 Example: mpeg2decode -b bitstream.mpg -f -r -o0 rec%%d\n\
316 \n");
317 exit(0);
318 }
319
320
321 Output_Type = 6; /* default: FBUI */
322 i = 1;
323
324 /* command-line options are proceeded by '-' */
325
326 while(i < argc)
327 {
328 /* check if this is the last argument */
329 LastArg = ((argc-i)==1);
330
331 /* parse ahead to see if another flag immediately follows current
332 argument (this is used to tell if a filename is missing) */
333 if(!LastArg)
334 NextArg = (argv[i+1][0]=='-');
335 else
336 NextArg = 0;
337
338 /* second character, [1], after '-' is the switch */
339 if(argv[i][0]=='-')
340 {
341 if (isdigit(argv[i][1])) {
342 fbui_console = -atoi(argv[i]);
343 }
344 else switch(toupper(argv[i][1]))
345 {
346 /* third character. [2], is the value */
347 case 'B':
348 Main_Bitstream_Flag = 1;
349
350 if(NextArg || LastArg)
351 {
352 printf("ERROR: -b must be followed the main bitstream filename\n");
353 }
354 else
355 Main_Bitstream_Filename = argv[++i];
356
357 break;
358
359
360 case 'C':
361
362 #ifdef VERIFY
363 Verify_Flag = atoi(&argv[i][2]);
364
365 if((Verify_Flag < NO_LAYER) || (Verify_Flag > ALL_LAYERS))
366 {
367 printf("ERROR: -c level (%d) out of range [%d,%d]\n",
368 Verify_Flag, NO_LAYER, ALL_LAYERS);
369 exit(ERROR);
370 }
371 #else /* VERIFY */
372 printf("This program not compiled for Verify_Flag option\n");
373 #endif /* VERIFY */
374 break;
375
376 case 'E':
377 Two_Streams = 1; /* either Data Partitioning (DP) or SNR Scalability enhancment */
378
379 if(NextArg || LastArg)
380 {
381 printf("ERROR: -e must be followed by filename\n");
382 exit(ERROR);
383 }
384 else
385 Enhancement_Layer_Bitstream_Filename = argv[++i];
386
387 break;
388
389
390 case 'F':
391 Frame_Store_Flag = 1;
392 break;
393
394 case 'G':
395 Big_Picture_Flag = 1;
396 break;
397
398
399 case 'I':
400 #ifdef VERIFY
401 Stats_Flag = atoi(&argv[i][2]);
402 #else /* VERIFY */
403 printf("WARNING: This program not compiled for -i option\n");
404 #endif /* VERIFY */
405 break;
406
407 case 'L': /* spatial scalability flag */
408 Spatial_Flag = 1;
409
410 if(NextArg || LastArg)
411 {
412 printf("ERROR: -l must be followed by filename\n");
413 exit(ERROR);
414 }
415 else
416 Lower_Layer_Picture_Filename = argv[++i];
417
418 break;
419
420 case 'O':
421
422 Output_Type = atoi(&argv[i][2]);
423
424 if((Output_Type==4) || (Output_Type==5) || Output_Type==6)
425 Output_Picture_Filename = ""; /* no need of filename */
426 else if(NextArg || LastArg)
427 {
428 printf("ERROR: -o must be followed by filename\n");
429 exit(ERROR);
430 }
431 else
432 /* filename is separated by space, so it becomes the next argument */
433 Output_Picture_Filename = argv[++i];
434
435 #ifdef DISPLAY
436 if (Output_Type==T_X11HIQ)
437 {
438 hiQdither = 1;
439 Output_Type=T_X11;
440 }
441 #endif /* DISPLAY */
442 break;
443
444 case 'Q':
445 Quiet_Flag = 1;
446 break;
447
448 case 'R':
449 Reference_IDCT_Flag = 1;
450 break;
451
452 case 'T':
453 #ifdef TRACE
454 Trace_Flag = 1;
455 #else /* TRACE */
456 printf("WARNING: This program not compiled for -t option\n");
457 #endif /* TRACE */
458 break;
459
460 case 'U':
461 User_Data_Flag = 1;
462
463 case 'V':
464 #ifdef VERBOSE
465 Verbose_Flag = atoi(&argv[i][2]);
466 #else /* VERBOSE */
467 printf("This program not compiled for -v option\n");
468 #endif /* VERBOSE */
469 break;
470
471
472 case 'X':
473 Ersatz_Flag = 1;
474
475 if(NextArg || LastArg)
476 {
477 printf("ERROR: -x must be followed by filename\n");
478 exit(ERROR);
479 }
480 else
481 Substitute_Picture_Filename = argv[++i];
482
483 break;
484
485
486
487 default:
488 fprintf(stderr,"undefined option -%c ignored. Exiting program\n",
489 argv[i][1]);
490
491 exit(ERROR);
492
493 } /* switch() */
494 } /* if argv[i][0] == '-' */
495
496 i++;
497
498 /* check for bitstream filename argument (there must always be one, at the very end
499 of the command line arguments */
500
501 } /* while() */
502
503
504 /* options sense checking */
505
506 if(Main_Bitstream_Flag!=1)
507 {
508 printf("There must be a main bitstream specified (-b filename)\n");
509 }
510
511 /* force display process to show frame pictures */
512 if((Output_Type==4 || Output_Type==5) && Frame_Store_Flag)
513 Display_Progressive_Flag = 1;
514 else
515 Display_Progressive_Flag = 0;
516
517 #ifdef VERIFY
518 /* parse the bitstream, do not actually decode it completely */
519
520
521 #if 0
522 if(Output_Type==-1)
523 {
524 Decode_Layer = Verify_Flag;
525 printf("FYI: Decoding bitstream elements up to: %s\n",
526 Layer_Table[Decode_Layer]);
527 }
528 else
529 #endif
530 Decode_Layer = ALL_LAYERS;
531
532 #endif /* VERIFY */
533
534 /* no output type specified */
535 if(Output_Type==-1)
536 {
537 Output_Type = 9;
538 Output_Picture_Filename = "";
539 }
540
541
542 #ifdef DISPLAY
543 if (Output_Type==T_X11)
544 {
545 if(Frame_Store_Flag)
546 Display_Progressive_Flag = 1;
547 else
548 Display_Progressive_Flag = 0;
549
550 Frame_Store_Flag = 1; /* to avoid calling dither() twice */
551 }
552 #endif
553
554
555 }
556
557
558 #ifdef OLD
559 /*
560 this is an old routine used to convert command line arguments
561 into integers
562 */
563 static int Get_Val(argv)
564 char *argv[];
565 {
566 int val;
567
568 if (sscanf(argv[1]+2,"%d",&val)!=1)
569 return 0;
570
571 while (isdigit(argv[1][2]))
572 argv[1]++;
573
574 return val;
575 }
576 #endif
577
578
579
580 static int Headers()
581 {
582 int ret;
583
584 ld = &base;
585
586
587 /* return when end of sequence (0) or picture
588 header has been parsed (1) */
589
590 ret = Get_Hdr();
591
592
593 if (Two_Streams)
594 {
595 ld = &enhan;
596 if (Get_Hdr()!=ret && !Quiet_Flag)
597 fprintf(stderr,"streams out of sync\n");
598 ld = &base;
599 }
600
601 return ret;
602 }
603
604
605
606 static int Decode_Bitstream()
607 {
608 int ret;
609 int Bitstream_Framenum;
610
611 Bitstream_Framenum = 0;
612
613 for(;;)
614 {
615
616 #ifdef VERIFY
617 Clear_Verify_Headers();
618 #endif /* VERIFY */
619
620 ret = Headers();
621
622 if(ret==1)
623 {
624 ret = video_sequence(&Bitstream_Framenum);
625 }
626 else
627 return(ret);
628 }
629
630 }
631
632
633 extern void shutdown_fbui();
634
635 static void Deinitialize_Sequence()
636 {
637 int i;
638
639 /* clear flags */
640 base.MPEG2_Flag=0;
641
642 for(i=0;i<3;i++)
643 {
644 free(backward_reference_frame[i]);
645 free(forward_reference_frame[i]);
646 free(auxframe[i]);
647
648 if (base.scalable_mode==SC_SPAT)
649 {
650 free(llframe0[i]);
651 free(llframe1[i]);
652 }
653 }
654
655 if (base.scalable_mode==SC_SPAT)
656 free(lltmp);
657
658 #ifdef DISPLAY
659 if (Output_Type==T_X11)
660 Terminate_Display_Process();
661 #endif
662 shutdown_fbui();
663 }
664
665
666 static int video_sequence(Bitstream_Framenumber)
667 int *Bitstream_Framenumber;
668 {
669 int Bitstream_Framenum;
670 int Sequence_Framenum;
671 int Return_Value;
672
673 Bitstream_Framenum = *Bitstream_Framenumber;
674 Sequence_Framenum=0;
675
676 Initialize_Sequence();
677
678 /* decode picture whose header has already been parsed in
679 Decode_Bitstream() */
680
681
682 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
683
684 /* update picture numbers */
685 if (!Second_Field)
686 {
687 Bitstream_Framenum++;
688 Sequence_Framenum++;
689 }
690
691 /* loop through the rest of the pictures in the sequence */
692 while ((Return_Value=Headers()))
693 {
694 Decode_Picture(Bitstream_Framenum, Sequence_Framenum);
695
696 if (!Second_Field)
697 {
698 Bitstream_Framenum++;
699 Sequence_Framenum++;
700 }
701 }
702
703 /* put last frame */
704 if (Sequence_Framenum!=0)
705 {
706 Output_Last_Frame_of_Sequence(Bitstream_Framenum);
707 }
708
709 Deinitialize_Sequence();
710
711 #ifdef VERIFY
712 Clear_Verify_Headers();
713 #endif /* VERIFY */
714
715 *Bitstream_Framenumber = Bitstream_Framenum;
716 return(Return_Value);
717 }
718
719
720
721 static void Clear_Options()
722 {
723 Verbose_Flag = 0;
724 Output_Type = 0;
725 Output_Picture_Filename = " ";
726 hiQdither = 0;
727 Output_Type = 0;
728 Frame_Store_Flag = 0;
729 Spatial_Flag = 0;
730 Lower_Layer_Picture_Filename = " ";
731 Reference_IDCT_Flag = 0;
732 Trace_Flag = 0;
733 Quiet_Flag = 0;
734 Ersatz_Flag = 0;
735 Substitute_Picture_Filename = " ";
736 Two_Streams = 0;
737 Enhancement_Layer_Bitstream_Filename = " ";
738 Big_Picture_Flag = 0;
739 Main_Bitstream_Flag = 0;
740 Main_Bitstream_Filename = " ";
741 Verify_Flag = 0;
742 Stats_Flag = 0;
743 User_Data_Flag = 0;
744 }
745
746
747 #ifdef DEBUG
748 static void Print_Options()
749 {
750
751 printf("Verbose_Flag = %d\n", Verbose_Flag);
752 printf("Output_Type = %d\n", Output_Type);
753 printf("Output_Picture_Filename = %s\n", Output_Picture_Filename);
754 printf("hiQdither = %d\n", hiQdither);
755 printf("Output_Type = %d\n", Output_Type);
756 printf("Frame_Store_Flag = %d\n", Frame_Store_Flag);
757 printf("Spatial_Flag = %d\n", Spatial_Flag);
758 printf("Lower_Layer_Picture_Filename = %s\n", Lower_Layer_Picture_Filename);
759 printf("Reference_IDCT_Flag = %d\n", Reference_IDCT_Flag);
760 printf("Trace_Flag = %d\n", Trace_Flag);
761 printf("Quiet_Flag = %d\n", Quiet_Flag);
762 printf("Ersatz_Flag = %d\n", Ersatz_Flag);
763 printf("Substitute_Picture_Filename = %s\n", Substitute_Picture_Filename);
764 printf("Two_Streams = %d\n", Two_Streams);
765 printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename);
766 printf("Big_Picture_Flag = %d\n", Big_Picture_Flag);
767 printf("Main_Bitstream_Flag = %d\n", Main_Bitstream_Flag);
768 printf("Main_Bitstream_Filename = %s\n", Main_Bitstream_Filename);
769 printf("Verify_Flag = %d\n", Verify_Flag);
770 printf("Stats_Flag = %d\n", Stats_Flag);
771 printf("User_Data_Flag = %d\n", User_Data_Flag);
772
773 }
774 #endif
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.