-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAbstractAVIStream.java
More file actions
1546 lines (1460 loc) · 66.6 KB
/
AbstractAVIStream.java
File metadata and controls
1546 lines (1460 loc) · 66.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* @(#)AbstractAVIStream.java
*
* Copyright (c) 2011 Werner Randelshofer, Immensee, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
import java.util.Map;
import java.awt.Dimension;
import java.awt.image.IndexColorModel;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.LinkedList;
import javax.imageio.stream.ImageOutputStream;
//import static VideoFormatKeys.*;
/**
* This is the base class for low-level AVI stream IO.
*
* @author Werner Randelshofer
* @version $Id: AbstractAVIStream.java 160 2012-01-28 17:07:17Z werner $
*/
public abstract class AbstractAVIStream {
/** Chunk IDs. */
protected final static int AVI_ID = 0x41564920;// "AVI "
protected final static int LIST_ID = 0x4c495354;// "LIST"
protected final static int MOVI_ID = 0x6d6f7669;// "movi"
protected final static int HDRL_ID = 0x6864726c;// "hdrl"
protected final static int AVIH_ID = 0x61766968;// "avih"
protected final static int STRL_ID = 0x7374726c;// "strl"
protected final static int STRH_ID = 0x73747268;// "strh"
protected final static int STRN_ID = 0x7374726e;// "strn"
protected final static int STRF_ID = 0x73747266;// "strf"
protected final static int STRD_ID = 0x73747264;// "strd"
protected final static int IDX1_ID = 0x69647831;// "idx1"
protected final static int REC_ID = 0x72656320;// "rec "
/** Indicates the AVI file has an index. */
public final static int AVIH_FLAG_HAS_INDEX = 0x00000010;
/** Indicates that application should use the index,
* rather than the physical ordering of the chunks in
* the file, to determine the order of presentation of
* the data. For example, this flag could be used to
* create a list of frames for editing.*/
public final static int AVIH_FLAG_MUST_USE_INDEX = 0x00000020;
/** Indicates the AVI file is interleaved.*/
public final static int AVIH_FLAG_IS_INTERLEAVED = 0x00000100;
/** ?? */
public final static int AVIH_FLAG_TRUST_CK_TYPE = 0x00000800;
/** // Indicates the AVI file is a specially allocated file
* used for capturing real-time video. Applications
* should warn the user before writing over a file with
* this flag set because the user probably defragmented
* this file. */
public final static int AVIH_FLAG_WAS_CAPTURE_FILE = 0x00010000;
/* Indicates the AVI file contains copyrighted data and
* software. When this flag is used, software should not
* permit the data to be duplicated. */
public final static int AVIH_FLAG_COPYRIGHTED = 0x00020000;
/** Indicates this stream should not be enabled by default. */
public final static int STRH_FLAG_DISABLED = 0x00000001;
/** Indicates this video stream contains palette changes. This flag
warns the playback software that it will need to animate the palette.*/
public final static int STRH_FLAG_VIDEO_PALETTE_CHANGES = 0x00010000;
/**
* Underlying output stream.
*/
protected ImageOutputStream out;
/** The offset in the underlying ImageOutputStream.
* Normally this is 0 unless the underlying stream already contained data
* when it was passed to the constructor.
*/
protected long streamOffset;
/**
* Supported media types.
*/
public static enum AVIMediaType {
AUDIO("auds"),//
MIDI("mids"),//
TEXT("txts"),//
VIDEO("vids")//
;
protected final String fccType;
@Override
public String toString() {
return fccType;
}
AVIMediaType(String fourCC) {
this.fccType = fourCC;
}
}
/** The list of tracks in the file. */
protected ArrayList<Track> tracks = new ArrayList<Track>();
/** Gets the position relative to the beginning of the QuickTime stream.
* <p>
* Usually this value is equal to the stream position of the underlying
* ImageOutputStream, but can be larger if the underlying stream already
* contained data.
*
* @return The relative stream position.
* @throws IOException
*/
protected long getRelativeStreamPosition() throws IOException {
return out.getStreamPosition() - streamOffset;
}
/** Seeks relative to the beginning of the AVI stream.
* <p>
* Usually this equal to seeking in the underlying ImageOutputStream, but
* can be different if the underlying stream already contained data.
*
*/
protected void seekRelative(long newPosition) throws IOException {
out.seek(newPosition + streamOffset);
}
/**
* AVI stores media data in sample chunks.
* A sample chunk may contain one or more media samples.
* A media sample is a single element in a sequence of time-ordered data.
*/
protected static class Sample {
String chunkType;
/** Offset of the sample chunk relative to the startTime of the AVI file.
*/
long offset;
/** Data length of the sample chunk. */
long length;
/** The number of media samples in the sample chunk. */
int duration;
/** Whether the sample is a sync-sample. */
boolean isKeyframe;
long timeStamp;
/** Palette change sample. */
Sample header;
/**
* Creates a new sample.
* @param duration The number of media samples contained in the sample
* chunk.
* @param offset The offset in the AVI stream.
* @param length The length in the AVI stream.
*/
public Sample(String chunkId, int duration, long offset, long length, boolean isSync) {
this.chunkType = chunkId;
this.duration = duration;
this.offset = offset;
this.length = length;
this.isKeyframe = isSync;
}
}
/** Represents a track (or "stream") in an AVI file.
* <p>
* A track is defined by an "strh" chunk, which contains an
* {@code AVISTREAMHEADER} struct. Additional chunks can be provided depending
* on the media type of the track.
* <p>
* See <a href="http://msdn.microsoft.com/en-us/library/ms779638(VS.85).aspx">
* http://msdn.microsoft.com/en-us/library/ms779638(VS.85).aspx</a>
* </p>
* <pre>
* -----------------
* AVI Stream Header
* -----------------
*
* enum {
* audioStream = "auds",
* midiStream = "mids",
* textStream = "txts",
* videoStream = "vids"
* } aviStrhType;
*
* set {
* disabled = 0x00000001, // Indicates this stream should not be enabled by default.
* videoPaletteChanges = 0x00010000
* // Indicates this video stream contains palette changes. This flag
* // warns the playback software that it will need to animate the palette.
*} aviStrhFlags;
*
*typedef struct {
* Int16 left;
* Int16 top;
* Int16 right;
* Int16 bottom;
*} aviRectangle;
*
*typedef struct {
* FOURCC enum aviStrhType type;
* // Contains a FOURCC that specifies the type of the data contained in
* // the stream. The following standard AVI values for video and audio are
* // defined.
* FOURCC handler;
* // Optionally, contains a FOURCC that identifies a specific data
* // handler.
* // The data handler is the preferred handler for the stream. For audio
* // and video streams, this specifies the codec for decoding the stream.
* DWORD set aviStrhFlags flags;
* // Contains any flags for the data stream. The bits in the high-order
* // word of these flags are specific to the type of data contained in the
* // stream.
* WORD priority;
* // Specifies priority of a stream type. For example, in a file with
* // multiple audio streams, the one with the highest priority might be
* // the default stream.
* WORD language;
* DWORD initialFrames;
* // Specifies how far audio data is skewed ahead of the video frames in
* // interleaved files. Typically, this is about 0.75 seconds. If you are
* // creating interleaved files, specify the number of frames in the file
* // prior to the initial frame of the AVI sequence in this member. For
* // more information about the contents of this member, see "Special
* // Information for Interleaved Files" in the Video for Windows
* // Programmer's Guide.
* DWORD scale;
* // Used with "rate" to specify the time scale that this stream will use.
* // Dividing "rate" by "scale" gives the number of samples per second.
* // For video streams, this is the frame rate. For audio streams, this
* // rate corresponds to the time needed to play blockAlign bytes of
* // audio, which for PCM audio is the just the sample rate.
* DWORD rate;
* // See "scale".
* DWORD startTime;
* // Specifies the starting time for this stream. The units are defined by
* // the "rate" and "scale" members in the main file header. Usually, this
* // is zero, but it can specify a delay time for a stream that does not
* // startTime concurrently with the file.
* DWORD length;
* // Specifies the length of this stream. The units are defined by the
* // "rate" and "scale" members of the stream's header.
* DWORD suggestedBufferSize;
* // Specifies how large a buffer should be used to read this stream.
* // Typically, this contains a value corresponding to the largest chunk
* // present in the stream. Using the correct buffer size makes playback
* // more efficient. Use zero if you do not know the correct buffer size.
* DWORD quality;
* // Specifies an indicator of the quality of the data in the stream.
* // Quality is represented as a number between 0 and 10,000. For
* // compressed data, this typically represents the value of the quality
* // parameter passed to the compression software. If set to �1, drivers
* // use the default quality value.
* DWORD sampleSize;
* // Specifies the size of a single sample of data. This is set to zero if
* // the samples can vary in size. If this number is nonzero, then
* // multiple samples of data can be grouped into a single chunk within
* // the file. If it is zero, each sample of data (such as a video frame)
* // must be in a separate chunk. For video streams, this number is
* // typically zero, although it can be nonzero if all video frames are
* // the same size. For audio streams, this number should be the same as
* // the blockAlign member of the WAVEFORMATEX structure describing the audio.
* aviRectangle frame;
* // Specifies the destination rectangle for a text or video stream within
* // the movie rectangle specified by the "frameWidth" and "frameHeight"
* // members of the AVI main header structure. The "frame" member is
* // typically used in support of multiple video streams. Set this
* // rectangle to the coordinates corresponding to the movie rectangle to
* // update the whole movie rectangle. Units for this member are pixels.
* // The upper-left corner of the destination rectangle is relative to the
* // upper-left corner of the movie rectangle.
* } AVISTREAMHEADER; * </pre>
*/
protected abstract class Track {
/**
* The media format.
*
* FIXME - AbstractAVIStream should have no dependencies to Format.
*/
protected Format format;
// Common metadata
/**
* The scale of the media in the track.
* <p>
* Used with rate to specify the time scale that this stream will use.
* Dividing rate by scale gives the number of samples per second.
* For video streams, this is the frame rate. For audio streams, this rate
* corresponds to the time needed to play blockAlign bytes of audio, which
* for PCM audio is just the sample rate.
*/
/**
* The rate of the media in scale units.
* <p>
* @see scale
*/
/**
* List of samples.
*/
protected ArrayList<Sample> samples;
/** Interval between sync samples (keyframes).
* 0 = automatic.
* 1 = write all samples as sync samples.
* n = sync every n-th sample.
*/
protected int syncInterval = 30;
/** The twoCC code is used for the ids of the chunks which hold the
* data samples.
*/
protected String twoCC;
//
// AVISTREAMHEADER structure
// -------------------------
/** {@code mediaType.fccType} contains a FOURCC that specifies the type
* of the data contained in
* the stream. The following standard AVI values for video and audio are
* defined.
*
* FOURCC Description
* 'auds' Audio stream
* 'mids' MIDI stream
* 'txts' Text stream
* 'vids' Video stream
**/
protected final AVIMediaType mediaType;
//protected String fccType;
/**
* Optionally, contains a FOURCC that identifies a specific data
* handler. The data handler is the preferred handler for the stream.
* For audio and video streams, this specifies the codec for decoding
* the stream.
*/
protected String fccHandler;
/** Contains any flags for the data stream. The bits in the high-order
* word of these flags are specific to the type of data contained in the
* stream. The following standard flags are defined.
*
* Value Description
*
* AVISF_DISABLED 0x00000001 Indicates this stream should not be enabled
* by default.
*
* AVISF_VIDEO_PALCHANGES 0x00010000 Indicates this video stream contains palette
* changes. This flag warns the playback
* software that it will need to animate the
* palette.
*/
protected int flags;
/** Specifies priority of a stream type. For example, in a file with
* multiple audio streams, the one with the highest priority might be
* the default stream.
*/
protected int priority = 0;
/** Language tag. */
protected int language = 0;
/** Specifies how far audio data is skewed ahead of the video frames in
* interleaved files. Typically, this is about 0.75 seconds. If you are
* creating interleaved files, specify the number of frames in the file
* prior to the initial frame of the AVI sequence in this member. For
* more information, see the remarks for the initialFrames member of
* the AVIMAINHEADER structure.
*/
protected long initialFrames = 0;
/** Used with rate to specify the time scale that this stream will
* use. Dividing rate by scale gives the number of samples per
* second. For video streams, this is the frame rate. For audio streams,
* this rate corresponds to the time needed to play blockAlign bytes of
* audio, which for PCM audio is the just the sample rate. */
protected long scale = 1;
/** The rate of the media in scale units. */
protected long rate = 30;
/** Specifies the starting time for this stream. The units are defined
* by the rate and scale members in the main file header. Usually,
* this is zero, but it can specify a delay time for a stream that does
* not startTime concurrently with the file.
*/
protected long startTime = 0;
/**
* Specifies the length of this stream. The units are defined by the
* rate and scale members of the stream's header.
*/
protected long length;
/**
* Specifies how large a buffer should be used to read this stream.
* Typically, this contains a value corresponding to the largest chunk
* present in the stream. Using the correct buffer size makes playback
* more efficient. Use zero if you do not know the correct buffer size.
*/
//protected long dwSuggestedBufferSize; => this field is computed from tr.samples
/** Specifies an indicator of the quality of the data in the stream.
* Quality is represented as a number between 0 and 10,000. For
* compressed data, this typically represents the value of the quality
* parameter passed to the compression software. If set to –1, drivers
* use the default quality value. */
protected int quality = -1;
/** Specifies the size of a single sample of data. This is set to zero
* if the samples can vary in size. If this number is nonzero, then
* multiple samples of data can be grouped into a single chunk within
* the file. If it is zero, each sample of data (such as a video frame)
* must be in a separate chunk. For video streams, this number is
* typically zero, although it can be nonzero if all video frames are
* the same size. For audio streams, this number should be the same as
* the blockAlign member of the WAVEFORMATEX structure describing the
* audio. */
//protected long dwSampleSize; => computed from tr.samples
/** Specifies the destination rectangle for a text or video stream
* within the movie rectangle specified by the dwWidth and dwHeight
* members of the AVI main header structure. The rcFrame member is
* typically used in support of multiple video streams. Set this
* rectangle to the coordinates corresponding to the movie rectangle to
* update the whole movie rectangle. Units for this member are pixels.
* The upper-left corner of the destination rectangle is relative to the
* upper-left corner of the movie rectangle. */
int frameLeft;
int frameTop;
int frameRight;
int frameBottom;
// --------------------------------
// End of AVISTREAMHEADER structure
/**
* This chunk holds the AVI Stream Header.
*/
protected FixedSizeDataChunk strhChunk;
/**
* This chunk holds the AVI Stream Format Header.
*/
protected FixedSizeDataChunk strfChunk;
/** The optional name of the track. */
protected String name;
/** The codec. */
protected Codec codec;
/** The output buffer is used to store the output of the codec. */
protected Buffer outputBuffer;
/** The input buffer is used when one of the convenience methods without a Buffer parameter
* is used. */
protected Buffer inputBuffer;
/** The current chunk index of the reader. */
protected long readIndex = 0;
/** List of additional header chunks. */
protected ArrayList<RIFFChunk> extraHeaders;
public Track(int trackIndex, AVIMediaType mediaType, String fourCC) {
this.mediaType = mediaType;
twoCC = "00" + Integer.toString(trackIndex);
twoCC = twoCC.substring(twoCC.length() - 2);
this.fccHandler = fourCC;
this.samples = new ArrayList<Sample>();
this.extraHeaders=new ArrayList<RIFFChunk>();
}
public abstract long getSTRFChunkSize();
public abstract String getSampleChunkFourCC(boolean isSync);
public void addSample(Sample s) {
if (!samples.isEmpty()) {
s.timeStamp = samples.get(samples.size() - 1).timeStamp + samples.get(samples.size() - 1).duration;
}
samples.add(s);
length++;
}
}
/** Represents a video track in an AVI file.
* <p>
* The format of a video track is defined in a "strf" chunk, which contains a
* {@code BITMAPINFOHEADER} struct.
*
* </pre>
* //----------------------
* // AVI Bitmap Info Header
* // ----------------------
* typedef struct {
* BYTE blue;
* BYTE green;
* BYTE red;
* BYTE reserved;
* } RGBQUAD;
*
* // Values for this enum taken from:
* // http://www.fourcc.org/index.php?http%3A//www.fourcc.org/rgb.php
* enum {
* BI_RGB = 0x00000000,
* RGB = 0x32424752, // Alias for BI_RGB
* BI_RLE8 = 0x01000000,
* RLE8 = 0x38454C52, // Alias for BI_RLE8
* BI_RLE4 = 0x00000002,
* RLE4 = 0x34454C52, // Alias for BI_RLE4
* BI_BITFIELDS = 0x00000003,
* raw = 0x32776173,
* RGBA = 0x41424752,
* RGBT = 0x54424752,
* cvid = "cvid"
* } bitmapCompression;
*
* typedef struct {
* DWORD structSize;
* // Specifies the number of bytes required by the structure.
* LONG width;
* // Specifies the width of the bitmap.
* // - For RGB formats, the width is specified in pixels.
* // - The same is true for YUV formats if the bitdepth is an even power
* // of 2.
* // - For YUV formats where the bitdepth is not an even power of 2,
* // however, the width is specified in bytes.
* // Decoders and video sources should propose formats where "width" is
* // the width of the image. If the video renderer is using DirectDraw, it
* // modifies the format so that "width" equals the stride of the surface,
* // and the "target" member of the VIDEOINFOHEADER or VIDEOINFOHEADER2
* // structure specifies the image width. Then it proposes the modified
* // format using IPin::QueryAccept.
* // For RGB and even-power-of-2 YUV formats, if the video renderer does
* // not specify the stride, then round the width up to the nearst DWORD
* // boundary to find the stride.
* LONG height;
* // Specifies the height of the bitmap, in pixels.
* // - For uncompressed RGB bitmaps, if "height" is positive, the bitmap
* // is a bottom-up DIB with the origin at the lower left corner. If
* // "height" is negative, the bitmap is a top-down DIB with the origin
* // at the upper left corner.
* // - For YUV bitmaps, the bitmap is always top-down, regardless of the
* // sign of "height". Decoders should offer YUV formats with postive
* // "height", but for backward compatibility they should accept YUV
* // formats with either positive or negative "height".
* // - For compressed formats, height must be positive, regardless of
* // image orientation.
* WORD planes;
* // Specifies the number of planes for the target device. This value must
* // be set to 1.
* WORD bitCount;
* // Specifies the number of bits per pixel.
* //DWORD enum bitmapCompression compression;
* FOURCC enum bitmapCompression compression;
* // If the bitmap is compressed, this member is a FOURCC the specifies
* // the compression.
* // Value Description
* // BI_RLE8 A run-length encoded (RLE) format for bitmaps with 8
* // bpp. The compression format is a 2-byte format
* // consisting of a count byte followed by a byte containing a color index. For more information, see Bitmap Compression.
* // BI_RLE4 An RLE format for bitmaps with 4 bpp. The compression
* // format is a 2-byte format consisting of a count byte
* // followed by two word-length color indexes. For more
* // information, see Bitmap Compression.
* // BI_JPEG Windows 98/Me, Windows 2000/XP: Indicates that the
* // image is a JPEG image.
* // BI_PNG Windows 98/Me, Windows 2000/XP: Indicates that the
* // image is a PNG image.
* // For uncompressed formats, the following values are possible:
* // Value Description
* // BI_RGB Uncompressed RGB.
* // BI_BITFIELDS Specifies that the bitmap is not compressed and that
* // the color table consists of three DWORD color masks
* // that specify the red, green, and blue components,
* // respectively, of each pixel. This is valid when used
* // with 16- and 32-bpp bitmaps.
* DWORD imageSizeInBytes;
* // Specifies the size, in bytes, of the image. This can be set to 0 for
* // uncompressed RGB bitmaps.
* LONG xPelsPerMeter;
* // Specifies the horizontal resolution, in pixels per meter, of the
* // target device for the bitmap.
* LONG yPelsPerMeter;
* // Specifies the vertical resolution, in pixels per meter, of the target
* // device for the bitmap.
* DWORD numberOfColorsUsed;
* // Specifies the number of color indices in the color table that are
* // actually used by the bitmap
* DWORD numberOfColorsImportant;
* // Specifies the number of color indices that are considered important
* // for displaying the bitmap. If this value is zero, all colors are
* // important.
* RGBQUAD colors[];
* // If the bitmap is 8-bpp or less, the bitmap uses a color table, which
* // immediately follows the BITMAPINFOHEADER. The color table consists of
* // an array of RGBQUAD values. The size of the array is given by the
* // "clrUsed" member. If "clrUsed" is zero, the array contains the
* // maximum number of colors for the given bitdepth; that is,
* // 2^"bitCount" colors.
* } BITMAPINFOHEADER;
* </pre>
*/
protected class VideoTrack extends Track {
// Video metadata
/**
* The video compression quality.
*/
protected float videoQuality = 0.97f;
/** Index color model for RAW_RGB4 and RAW_RGB8 formats. */
protected IndexColorModel palette;
protected IndexColorModel previousPalette;
/** Previous frame for delta compression. */
protected Object previousData;
//protected Rectangle rcFrame;
// BITMAPINFOHEADER structure
/**
* Specifies the number of bytes required by the structure. This value
* does not include the size of the color table or the size of the color
* masks, if they are appended to the end of structure.
*/
//protected long biSize; => computed when writing chukn
/**
* Specifies the width of the bitmap, in pixels. For information about
* calculating the stride of the bitmap.
*/
int width;
/**
* Specifies the height of the bitmap, in pixels.
*
* For uncompressed RGB bitmaps, if height is positive, the bitmap is a
* bottom-up DIB with the origin at the lower left corner. If height is
* negative, the bitmap is a top-down DIB with the origin at the upper left
* corner.
* For YUV bitmaps, the bitmap is always top-down, regardless of the sign of
* height. Decoders should offer YUV formats with positive height, but
* for backward compatibility they should accept YUV formats with either
* positive or negative height.
* For compressed formats, height must be positive, regardless of image
* orientation.
*/
int height;
/**
* Specifies the number of planes for the target device. This value must be
* set to 1.
*/
int planes;
/**
* Specifies the number of bits per pixel (bpp). For uncompressed formats,
* this value is the average number of bits per pixel. For compressed
* formats, this value is the implied bit depth of the uncompressed image,
* after the image has been decoded.
*/
int bitCount;
/**
* For compressed video and YUV formats, this member is a FOURCC code,
* specified as a DWORD in little-endian order. For example, YUYV video has
* the FOURCC 'VYUY' or 0x56595559.
*
* For uncompressed RGB formats, the following values are possible:
*
* Value Description
*
* BI_RGB Uncompressed RGB.
*
* BI_BITFIELDS Uncompressed RGB with color masks.
* Valid for 16-bpp and 32-bpp bitmaps.
*
* Note that BI_JPG and BI_PNG are not valid video formats.
*
* For 16-bpp bitmaps, if compression equals BI_RGB, the format is always
* RGB 555. If compression equals BI_BITFIELDS, the format is either
* RGB 555 or RGB 565. Use the subtype GUID in the AM_MEDIA_TYPE structure
* to determine the specific RGB type.
*/
String compression;
/**
* Specifies the size, in bytes, of the image. This can be set to 0 for
* uncompressed RGB bitmaps.
*/
long sizeImage;
/**
* Specifies the horizontal resolution, in pixels per meter, of the target
* device for the bitmap.
*/
long xPelsPerMeter;
/**
* Specifies the vertical resolution, in pixels per meter, of the target
* device for the bitmap.
*/
long yPelsPerMeter;
/**
* Specifies the number of color indices in the color table that are
* actually used by the bitmap. See Remarks for more information.
*/
long clrUsed;
/**
* Specifies the number of color indices that are considered important for
* displaying the bitmap. If this value is zero, all colors are important.
*/
long clrImportant;
private String sampleChunkFourCC;
public VideoTrack(int trackIndex, String fourCC, Format videoFormat) {
super(trackIndex, AVIMediaType.VIDEO, fourCC);
this.format = videoFormat;
sampleChunkFourCC = videoFormat != null && videoFormat.get(VideoFormatKeys.EncodingKey).equals(VideoFormatKeys.ENCODING_AVI_DIB) ? twoCC + "db" : twoCC + "dc";
}
@Override
public long getSTRFChunkSize() {
return palette == null ? 40 : 40 + palette.getMapSize() * 4;
}
@Override
public String getSampleChunkFourCC(boolean isSync) {
return sampleChunkFourCC;
}
}
/**
* <p>
* The format of a video track is defined in a "strf" chunk, which contains a
* {@code WAVEFORMATEX} struct.
* <pre>
* ----------------------
* AVI Wave Format Header
* ----------------------
* // values for this enum taken from mmreg.h
* enum {
* WAVE_FORMAT_PCM = 0x0001,
* // Microsoft Corporation
* WAVE_FORMAT_ADPCM = 0x0002,
* // Microsoft Corporation
* * IEEE754: range (+1, -1]
* * 32-bit/64-bit format as defined by
* * MSVC++ float/double type
*
* WAVE_FORMAT_IEEE_FLOAT = 0x0003,
* // IBM Corporation
* WAVE_FORMAT_IBM_CVSD = 0x0005,
* // Microsoft Corporation
* WAVE_FORMAT_ALAW = 0x0006,
* // Microsoft Corporation
* WAVE_FORMAT_MULAW = 0x0007,
* // OKI
* WAVE_FORMAT_OKI_ADPCM = 0x0010,
* // Intel Corporation
* WAVE_FORMAT_DVI_ADPCM = 0x0011,
* // Intel Corporation
* WAVE_FORMAT_IMA_ADPCM = 0x0011,
* // Videologic
* WAVE_FORMAT_MEDIASPACE_ADPCM = 0x0012,
* // Sierra Semiconductor Corp
* WAVE_FORMAT_SIERRA_ADPCM = 0x0013,
* // Antex Electronics Corporation
* WAVE_FORMAT_G723_ADPCM = 0x0014,
* // DSP Solutions, Inc.
* WAVE_FORMAT_DIGISTD = 0x0015,
* // DSP Solutions, Inc.
* WAVE_FORMAT_DIGIFIX = 0x0016,
* // Dialogic Corporation
* WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017,
* // Media Vision, Inc.
* WAVE_FORMAT_MEDIAVISION_ADPCM = 0x0018,
* // Yamaha Corporation of America
* WAVE_FORMAT_YAMAHA_ADPCM = 0x0020,
* // Speech Compression
* WAVE_FORMAT_SONARC = 0x0021,
* // DSP Group, Inc
* WAVE_FORMAT_DSPGROUP_TRUESPEECH = 0x0022,
* // Echo Speech Corporation
* WAVE_FORMAT_ECHOSC1 = 0x0023,
* //
* WAVE_FORMAT_AUDIOFILE_AF36 = 0x0024,
* // Audio Processing Technology
* WAVE_FORMAT_APTX = 0x0025,
* //
* WAVE_FORMAT_AUDIOFILE_AF10 = 0x0026,
* // Dolby Laboratories
* WAVE_FORMAT_DOLBY_AC2 = 0x0030,
* // Microsoft Corporation
* WAVE_FORMAT_GSM610 = 0x0031,
* // Microsoft Corporation
* WAVE_FORMAT_MSNAUDIO = 0x0032,
* // Antex Electronics Corporation
* WAVE_FORMAT_ANTEX_ADPCME = 0x0033,
* // Control Resources Limited
* WAVE_FORMAT_CONTROL_RES_VQLPC = 0x0034,
* // DSP Solutions, Inc.
* WAVE_FORMAT_DIGIREAL = 0x0035,
* // DSP Solutions, Inc.
* WAVE_FORMAT_DIGIADPCM = 0x0036,
* // Control Resources Limited
* WAVE_FORMAT_CONTROL_RES_CR10 = 0x0037,
* // Natural MicroSystems
* WAVE_FORMAT_NMS_VBXADPCM = 0x0038,
* // Crystal Semiconductor IMA ADPCM
* WAVE_FORMAT_CS_IMAADPCM = 0x0039,
* // Echo Speech Corporation
* WAVE_FORMAT_ECHOSC3 = 0x003A,
* // Rockwell International
* WAVE_FORMAT_ROCKWELL_ADPCM = 0x003B,
* // Rockwell International
* WAVE_FORMAT_ROCKWELL_DIGITALK = 0x003C,
* // Xebec Multimedia Solutions Limited
* WAVE_FORMAT_XEBEC = 0x003D,
* // Antex Electronics Corporation
* WAVE_FORMAT_G721_ADPCM = 0x0040,
* // Antex Electronics Corporation
* WAVE_FORMAT_G728_CELP = 0x0041,
* // Microsoft Corporation
* WAVE_FORMAT_MPEG = 0x0050,
* // ISO/MPEG Layer3 Format Tag
* WAVE_FORMAT_MPEGLAYER3 = 0x0055,
* // Cirrus Logic
* WAVE_FORMAT_CIRRUS = 0x0060,
* // ESS Technology
* WAVE_FORMAT_ESPCM = 0x0061,
* // Voxware Inc
* WAVE_FORMAT_VOXWARE = 0x0062,
* // Canopus, co., Ltd.
* WAVE_FORMAT_CANOPUS_ATRAC = 0x0063,
* // APICOM
* WAVE_FORMAT_G726_ADPCM = 0x0064,
* // APICOM
* WAVE_FORMAT_G722_ADPCM = 0x0065,
* // Microsoft Corporation
* WAVE_FORMAT_DSAT = 0x0066,
* // Microsoft Corporation
* WAVE_FORMAT_DSAT_DISPLAY = 0x0067,
* // Softsound, Ltd.
* WAVE_FORMAT_SOFTSOUND = 0x0080,
* // Rhetorex Inc
* WAVE_FORMAT_RHETOREX_ADPCM = 0x0100,
* // Creative Labs, Inc
* WAVE_FORMAT_CREATIVE_ADPCM = 0x0200,
* // Creative Labs, Inc
* WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 0x0202,
* // Creative Labs, Inc
* WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 0x0203,
* // Quarterdeck Corporation
* WAVE_FORMAT_QUARTERDECK = 0x0220,
* // Fujitsu Corp.
* WAVE_FORMAT_FM_TOWNS_SND = 0x0300,
* // Brooktree Corporation
* WAVE_FORMAT_BTV_DIGITAL = 0x0400,
* // Ing C. Olivetti & C., S.p.A.
* WAVE_FORMAT_OLIGSM = 0x1000,
* // Ing C. Olivetti & C., S.p.A.
* WAVE_FORMAT_OLIADPCM = 0x1001,
* // Ing C. Olivetti & C., S.p.A.
* WAVE_FORMAT_OLICELP = 0x1002,
* // Ing C. Olivetti & C., S.p.A.
* WAVE_FORMAT_OLISBC = 0x1003,
* // Ing C. Olivetti & C., S.p.A.
* WAVE_FORMAT_OLIOPR = 0x1004,
* // Lernout & Hauspie
* WAVE_FORMAT_LH_CODEC = 0x1100,
* // Norris Communications, Inc.
* WAVE_FORMAT_NORRIS = 0x1400,
* //
* * the WAVE_FORMAT_DEVELOPMENT format tag can be used during the
* * development phase of a new wave format. Before shipping, you MUST
* * acquire an official format tag from Microsoft.
*
* WAVE_FORMAT_DEVELOPMENT = 0xFFFF,
* } wFormatTagEnum;
*
* typedef struct {
* WORD enum wFormatTagEnum formatTag;
* // Waveform-audio format type. Format tags are registered with Microsoft
* // Corporation for many compression algorithms. A complete list of format
* // tags can be found in the Mmreg.h header file. For one- or two-channel
* // Pulse Code Modulation (PCM) data, this value should be WAVE_FORMAT_PCM.
* WORD numberOfChannels;
* // Number of channels in the waveform-audio data. Monaural data uses one
* // channel and stereo data uses two channels.
* DWORD samplesPerSec;
* // Sample rate, in samples per second (hertz). If "formatTag" is
* // "WAVE_FORMAT_PCM", then common values for "samplesPerSec" are 8.0 kHz,
* // 11.025 kHz, 22.05 kHz, and 44.1 kHz. For non-PCM formats, this member
* // must be computed according to the manufacturer's specification of the
* // format tag.
* DWORD avgBytesPerSec;
* // Required average data-transfer rate, in bytes per second, for the format
* // tag. If "formatTag" is "WAVE_FORMAT_PCM", "avgBytesPerSec" should be
* // equal to the product of "samplesPerSec" and "blockAlignment". For non-PCM
* // formats, this member must be computed according to the manufacturer's
* // specification of the format tag.
* WORD blockAlignment;
* // Block alignment, in bytes. The block alignment is the minimum atomic unit
* // of data for the "formatTag" format type. If "formatTag" is
* // "WAVE_FORMAT_PCM" or "WAVE_FORMAT_EXTENSIBLE, "blockAlignment" must be equal
* // to the product of "numberOfChannels" and "bitsPerSample" divided by 8 (bits per
* // byte). For non-PCM formats, this member must be computed according to the
* // manufacturer's specification of the format tag.
* // Software must process a multiple of "blockAlignment" bytes of data at a
* // time. Data written to and read from a device must always start at the
* // beginning of a block. For example, it is illegal to start playback of PCM
* // data in the middle of a sample (that is, on a non-block-aligned boundary).
* WORD bitsPerSample;
* // Bits per sample for the waveFormatTag format type. If "formatTag" is
* // "WAVE_FORMAT_PCM", then "bitsPerSample" should be equal to 8 or 16. For
* // non-PCM formats, this member must be set according to the manufacturer's
* // specification of the format tag. If "formatTag" is
* // "WAVE_FORMAT_EXTENSIBLE", this value can be any integer multiple of 8.
* // Some compression schemes cannot define a value for "bitsPerSample", so
* // this member can be zero.
* WORD cbSize;
* // Size, in bytes, of extra format information appended to the end of the
* // WAVEFORMATEX structure. This information can be used by non-PCM formats
* // to store extra attributes for the "wFormatTag". If no extra information
* // is required by the "wFormatTag", this member must be set to zero. For
* // WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member
* // is ignored.
* byte[cbSize] extra;
* } WAVEFORMATEX;
* </pre>
*/
protected class AudioTrack extends Track {
// WAVEFORMATEX Structure
/**
* Waveform-audio format type. Format tags are registered with Microsoft
* Corporation for many compression algorithms. A complete list of
* format tags can be found in the Mmreg.h header file. For one- or
* two-channel Pulse Code Modulation (PCM) data, this value should be
* WAVE_FORMAT_PCM=0x0001.
*
* If wFormatTag equals WAVE_FORMAT_EXTENSIBLE=0xFFFE, the structure is
* interpreted as a WAVEFORMATEXTENSIBLE structure.
* If wFormatTag equals WAVE_FORMAT_MPEG, the structure is interpreted
* as an MPEG1WAVEFORMAT structure.
* If wFormatTag equals MPEGLAYER3WAVEFORMAT, the structure is
* interpreted as an MPEGLAYER3WAVEFORMAT structure.
* Before reinterpreting a WAVEFORMATEX structure as one of these
* extended structures, verify that the actual structure size is
* sufficiently large and that the cbSize member indicates a valid size.
*/
protected int wFormatTag;
/** Number of channels in the waveform-audio data. Monaural data uses
* one channel and stereo data uses two channels.
*/
protected int channels;
/**
* Sample rate, in samples per second (hertz). If wFormatTag is
* WAVE_FORMAT_PCM, then common values for samplesPerSec are 8.0 kHz,
* 11.025 kHz, 22.05 kHz, and 44.1 kHz. For non-PCM formats, this member
* must be computed according to the manufacturer's specification of the
* format tag.
*/
protected long samplesPerSec;
/**
* Required average data-transfer rate, in bytes per second, for the
* format tag. If wFormatTag is WAVE_FORMAT_PCM, avgBytesPerSec should
* be equal to the product of samplesPerSec and blockAlign. For
* non-PCM formats, this member must be computed according to the
* manufacturer's specification of the format tag.
*/
protected long avgBytesPerSec;
/**
* Block alignment, in bytes. The block alignment is the minimum atomic
* unit of data for the wFormatTag format type. If wFormatTag is
* WAVE_FORMAT_PCM or WAVE_FORMAT_EXTENSIBLE, blockAlign must be equal
* to the product of channels and bitsPerSample divided by 8 (bits per
* byte). For non-PCM formats, this member must be computed according to
* the manufacturer's specification of the format tag.
*
* Software must process a multiple of blockAlign bytes of data at a
* time. Data written to and read from a device must always startTime at the
* beginning of a block. For example, it is illegal to startTime playback of
* PCM data in the middle of a sample (that is, on a non-block-aligned
* boundary).
*/
protected int blockAlign;
/**
* Bits per sample for the wFormatTag format type. If wFormatTag is
* WAVE_FORMAT_PCM, then bitsPerSample should be equal to 8 or 16.
* For non-PCM formats, this member must be set according to the
* manufacturer's specification of the format tag. If wFormatTag is
* WAVE_FORMAT_EXTENSIBLE, this value can be any integer multiple of 8.
* Some compression schemes cannot define a value for bitsPerSample, so
* this member can be zero.
*/
protected int bitsPerSample;
/**
* Size, in bytes, of extra format information appended to the end of
* the WAVEFORMATEX structure. This information can be used by non-PCM
* formats to store extra attributes for the wFormatTag. If no extra
* information is required by the wFormatTag, this member must be set to
* zero. For WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats),
* this member is ignored.
*/
//int cbSize; => this value is computed
// Well known wave format tags
/** Microsoft Corporation */
protected final static int WAVE_FORMAT_PCM = 0x0001;
/** Microsoft Corporation */
protected final static int WAVE_FORMAT_ADPCM = 0x0002;
/** Microsoft Corporation
* IEEE754: range (+1, -1]
* 32-bit/64-bit format as defined by
* MSVC++ float/double type
*/
protected final static int WAVE_FORMAT_IEEE_FLOAT = 0x0003;
/** IBM Corporation */
protected final static int WAVE_FORMAT_IBM_CVSD = 0x0005;
/** Microsoft Corporation */
protected final static int WAVE_FORMAT_ALAW = 0x0006;
/** Microsoft Corporation */
protected final static int WAVE_FORMAT_MULAW = 0x0007;
/** OKI */
protected final static int WAVE_FORMAT_OKI_ADPCM = 0x0010;
/** Intel Corporation */
protected final static int WAVE_FORMAT_DVI_ADPCM = 0x0011;
/** Intel Corporation */