arduino-audio-tools
Loading...
Searching...
No Matches
ContainerAVI.h
Go to the documentation of this file.
1#pragma once
2#include <string.h>
10
11#define LIST_HEADER_SIZE 12
12#define CHUNK_HEADER_SIZE 8
13
14namespace audio_tools {
15
24public:
25 size_t writeArray(uint8_t *data, size_t len) {
26 int to_write = min(availableToWrite(), (size_t)len);
27 memmove(vector.data() + available_byte_count, data, to_write);
28 available_byte_count += to_write;
29 return to_write;
30 }
31 void consume(int size) {
32 // use pointer arithmetic (not the bounds-checked operator[]): when size
33 // == available_byte_count (buffer fully drained, common for chunks at
34 // least as big as the buffer capacity, e.g. large raw video frames),
35 // vector.data() + size legally points one-past-the-end and the memmove
36 // length is 0, which operator[] would reject even though it's a no-op
39 }
40 bool resize(size_t size) {
41 vector.resize(size + 4);
42 return vector.data() != nullptr;
43 }
44
45 uint8_t *data() { return vector.data(); }
46
48
49 size_t available() { return available_byte_count; }
50
51 void clear() {
53 memset(vector.data(), 0, vector.size());
54 }
55
56 bool isEmpty() { return available_byte_count == 0; }
57
58 size_t size() { return vector.size(); }
59
60 long indexOf(const char *str) {
61 uint8_t *ptr = (uint8_t *)memmem(vector.data(), available_byte_count, str,
62 strlen(str));
63 return ptr == nullptr ? -1l : ptr - vector.data();
64 }
65
66protected:
69};
70
73using FOURCC = char[4];
74
76 // FOURCC fcc;
77 // uint32_t cb;
81 uint32_t dwFlags;
82 uint32_t dwTotalFrames;
84 uint32_t dwStreams;
86 uint32_t dwWidth;
87 uint32_t dwHeight;
88 uint32_t dwReserved[4];
89};
90
91struct RECT {
92 uint32_t dwWidth;
93 uint32_t dwHeight;
94};
95
112
113// field widths mirror the on-disk 40-byte BITMAPINFOHEADER exactly (all
114// DWORD/uint32_t, except the two WORD/uint16_t fields) - do not widen these,
115// the decoder reinterpret_casts raw file bytes directly onto this struct
117 uint32_t biSize;
118 uint32_t biWidth;
119 uint32_t biHeight;
120 uint16_t biPlanes;
121 uint16_t biBitCount;
123 uint32_t biSizeImage;
126 uint32_t biClrUsed;
128};
129
139
140// struct WAVFormat {
141// uint16_t wFormatTag;
142// uint16_t nChannels;
143// uint32_t nSamplesPerSec;
144// uint32_t nAvgBytesPerSec;
145// uint16_t nBlockAlign;
146// };
147
149
163
171public:
172 void set(size_t currentPos, StrView id, size_t size, ParseObjectType type) {
173 set(currentPos, id.c_str(), size, type);
174 }
175
176 void set(size_t currentPos, const char *id, size_t size,
179 data_size = size;
181 start_pos = currentPos;
182 // allign on word
183 if (size % 2 != 0) {
184 data_size++;
185 }
186 end_pos = currentPos + data_size + 4;
187 // save FOURCC
188 if (id != nullptr) {
189 memcpy(chunk_id, id, 4);
190 chunk_id[4] = 0;
191 }
192 open = data_size;
193 }
194 const char *id() { return chunk_id; }
195 size_t size() { return data_size; }
199 size_t declaredSize() { return declared_size; }
200
202 bool isValid() {
203 switch (object_type) {
204 case AVIStreamData:
205 return isAudio() || isVideo();
206 case AVIChunk:
207 return open > 0;
208 case AVIList:
209 return true;
210 }
211 return false;
212 }
213
214 // for Chunk
215 AVIMainHeader *asAVIMainHeader(void *ptr) { return (AVIMainHeader *)ptr; }
217 return (AVIStreamHeader *)ptr;
218 }
219 WAVFormatX *asAVIAudioFormat(void *ptr) { return (WAVFormatX *)ptr; }
221 return (BitmapInfoHeader *)ptr;
222 }
223
224 size_t open;
225 size_t end_pos;
226 size_t start_pos;
227 size_t data_size;
229
230 // for AVIStreamData
232 return object_type == AVIStreamData ? (chunk_id[1] << 8) | chunk_id[0] : 0;
233 }
234 bool isAudio() {
235 return object_type == AVIStreamData
236 ? chunk_id[2] == 'w' && chunk_id[3] == 'b'
237 : false;
238 }
240 return object_type == AVIStreamData
241 ? chunk_id[2] == 'd' && chunk_id[3] == 'b'
242 : false;
243 }
245 return object_type == AVIStreamData
246 ? chunk_id[2] == 'd' && chunk_id[3] == 'c'
247 : false;
248 }
250
251protected:
252 // ParseBuffer data_buffer;
253 char chunk_id[5] = {};
255};
256
269class DemuxerAVI : public Demuxer {
270public:
279 DemuxerAVI(int bufferSize = 1024) {
280 parse_buffer.resize(bufferSize);
281 }
282
283 const char *mime() override { return "video/avi"; }
284
293 void setSendWavHeader(bool flag) override {
294 send_wav_header = flag;
296 }
297
298 bool begin() override {
300 header_is_avi = false;
301 is_parsing_active = true;
302 current_pos = 0;
303 header_is_avi = false;
305 is_metadata_ready = false;
306 is_wav_header_sent = false;
307 riff_file_size = 0;
308 return true;
309 }
310
314 void setOutputAudio(Print &out_stream) override {
315 p_output_audio = &out_stream;
316 }
317
322 virtual void setOutput(Print &out_stream) override {
323 setOutputAudio(out_stream);
324 }
325
327 void setMute(bool mute) { is_mute = mute; }
328
329 virtual void setOutputVideo(Print &out_stream) override {
330 p_output_video = &out_stream;
331 }
332 void setOutputVideo(VideoOutput &out_stream) {
333 p_output_video_video = &out_stream;
334 }
335
336 virtual size_t write(const uint8_t *data, size_t len) override {
337 LOGD("write: %d", (int)len);
338 int result = parse_buffer.writeArray((uint8_t *)data, len);
339 if (is_parsing_active) {
340 // we expect the first parse to succeed
341 if (parse()) {
342 // if so we process the parse_buffer
343 while (parse_buffer.available() > 4) {
344 if (!parse())
345 break;
346 }
347 } else {
348 LOGD("Parse Error");
350 result = len;
351 is_parsing_active = false;
352 }
353 }
354 return result;
355 }
356
357 operator bool() override { return is_parsing_active; }
358
359 void end() override { is_parsing_active = false; };
360
363
366
369
370 const char *aviVideoFormat() { return video_format; }
371
374
382 VideoInfo result;
383 result.width = (uint16_t)video_info.biWidth;
384 result.height = (uint16_t)video_info.biHeight;
385 result.format =
387 result.frame_size =
388 (uint32_t)videoFrameSizeBytes(result.format, result.width, result.height);
390 return result;
391 }
392
393
404 AudioInfoFormat result(info);
406 return result;
407 }
408
413 void setValidationCallback(bool (*cb)(DemuxerAVI &avi)) {
414 validation_cb = cb;
415 }
416
418 int videoSeconds() { return video_seconds; }
419
421 void setVideoAudioSync(VideoAudioSync *yourSync) { p_synch = yourSync; }
422
423protected:
424 bool header_is_avi = false;
425 bool is_parsing_active = true;
441 long current_pos = 0;
442 long movi_end_pos = 0;
445 char video_format[5] = {0};
446 bool is_metadata_ready = false;
447 bool (*validation_cb)(DemuxerAVI &avi) = nullptr;
448 bool is_mute = false;
449 bool send_wav_header = false;
451 bool is_wav_header_sent = false;
455 uint32_t riff_file_size = 0;
459
461 return strncmp(stream_header[stream_header_idx].fccType, "auds", 4) == 0;
462 }
463
465 return strncmp(stream_header[stream_header_idx].fccType, "vids", 4) == 0;
466 }
467
468 // we return true if at least one parse step was successful
469 bool parse() {
470 bool result = true;
471 switch (parse_state) {
472 case ParseHeader: {
473 result = parseHeader();
474 if (result)
476 } break;
477
478 case ParseHdrl: {
479 ParseObject hdrl = parseList("hdrl");
480 result = hdrl.isValid();
481 if (result) {
483 }
484 } break;
485
486 case ParseAvih: {
487 ParseObject avih = parseChunk("avih");
488 result = avih.isValid();
489 if (result) {
492 consume(avih.size());
494 }
495 } break;
496
497 case ParseStrl: {
498 ParseObject strl = parseList("strl");
499 ParseObject strh = parseChunk("strh");
502 consume(strh.size());
504 } break;
505
506 case ParseStrf: {
507 ParseObject strf = parseChunk("strf");
508 if (isCurrentStreamAudio()) {
511 LOGI("audioFormat: %d (%x)", (int)audio_info.wFormatTag,
514 consume(strf.size());
515 } else if (isCurrentStreamVideo()) {
518 LOGI("videoFormat: %s", aviVideoFormat());
520 video_format[4] = 0;
521 consume(strf.size());
522 } else {
523 result = false;
524 }
526 } break;
527
528 case AfterStrf: {
529 // ignore all data until we find a new List
530 int pos = parse_buffer.indexOf("LIST");
531 if (pos >= 0) {
532 consume(pos);
534 if (StrView(tmp.id()).equals("strl")) {
536 } else if (StrView(tmp.id()).equals("movi")) {
538 } else {
539 // e.g. ignore info
541 }
542 } else {
543 // no valid data, so throw it away, we keep the last 4 digits in case
544 // if it contains the beginning of a LIST
545 cleanupStack();
547 }
548 } break;
549
550 case ParseMovi: {
551 ParseObject movi = tryParseList();
552 if (StrView(movi.id()).equals("movi")) {
554 is_metadata_ready = true;
555 if (validation_cb)
557 processStack(movi);
558 movi_end_pos = movi.end_pos;
560 // trigger new write
561 result = false;
562 }
563 } break;
564
565 case SubChunk: {
566 // rec is optinal
567 ParseObject hdrl = tryParseList();
568 if (StrView(hdrl.id()).equals("rec")) {
570 processStack(hdrl);
571 }
572
577 LOGI("video:[%d]->[%d]", (int)current_stream_data.start_pos,
580 } else if (current_stream_data.isAudio()) {
581 LOGI("audio:[%d]->[%d]", (int)current_stream_data.start_pos,
583 } else {
584 LOGW("unknown subchunk at %d", (int)current_pos);
585 }
586
587 } break;
588
589 case SubChunkContinue: {
590 writeData();
591 if (open_subchunk_len == 0) {
593 (p_output_video != nullptr || p_output_video_video != nullptr)) {
594 if (p_output_video != nullptr) p_output_video->flush();
596 uint32_t time_used_ms = (uint32_t)(millis() - video_frame_start_ms);
598 }
599 if (tryParseChunk("idx").isValid()) {
601 } else if (tryParseList("rec").isValid()) {
603 } else {
604 if (current_pos >= movi_end_pos) {
606 } else {
608 }
609 }
610 }
611 } break;
612
613 case ParseIgnore: {
614 LOGD("ParseIgnore");
616 } break;
617
618 default:
619 result = false;
620 break;
621 }
622 return result;
623 }
624
635
643 if (is_wav_header_sent || p_output_audio == nullptr) return;
644 WAVAudioInfo winfo(info);
646 winfo.is_streamed = true;
649 winfo.ext_adpcm_header = true;
650 WAVHeader wav_header;
651 wav_header.setAudioInfo(winfo);
652 wav_header.writeHeader(p_output_audio);
653 is_wav_header_sent = true;
654 }
655
657 memcpy(video_format, stream_header[stream_header_idx].fccHandler, 4);
659 if (vh->dwScale <= 0) {
660 vh->dwScale = 1;
661 }
662 int rate = vh->dwRate / vh->dwScale;
663 video_seconds = rate <= 0 ? 0 : vh->dwLength / rate;
664 LOGI("videoSeconds: %d seconds", video_seconds);
665 }
666
671 static VideoFormat toVideoFormat(uint32_t biCompression,
672 uint16_t biBitCount) {
673 if (biCompression == 0) return VideoFormat::RAW; // BI_RGB
674 if (biCompression == 3) // BI_BITFIELDS
675 return biBitCount == 16 ? VideoFormat::RGB565 : VideoFormat::RAW;
676
677 auto is = [biCompression](const char *fourcc) {
678 return memcmp(&biCompression, fourcc, 4) == 0;
679 };
680 if (is("H264") || is("h264") || is("X264") || is("x264") ||
681 is("avc1") || is("AVC1"))
682 return VideoFormat::H264;
683 if (is("MJPG") || is("mjpg"))
684 return VideoFormat::MJPEG;
685 if (is("FMP4") || is("XVID") || is("DIVX") || is("DX50") ||
686 is("mp4v"))
687 return VideoFormat::MPEG4;
688 if (is("YUY2") || is("YUYV") || is("yuy2") || is("yuyv"))
689 return VideoFormat::YUV422;
690 if (is("I420") || is("IYUV"))
691 return VideoFormat::I420;
692 if (is("RGBP"))
693 return VideoFormat::RGB565;
695 }
696
697 void writeData() {
698 long to_write = min((long)parse_buffer.available(), open_subchunk_len);
699 // open_subchunk_len spans the word-aligned chunk (current_stream_data
700 // .size()), which for an odd declared size includes a trailing RIFF pad
701 // byte that must be consumed from the buffer but not delivered as
702 // payload to the audio/video sink - clip to the real, unpadded length.
703 long already_written = (long)current_stream_data.size() - open_subchunk_len;
704 long payload_left = (long)current_stream_data.declaredSize() - already_written;
705 if (payload_left < 0) payload_left = 0;
706 long payload_to_write = min(to_write, payload_left);
707
709 LOGD("audio %d", (int)to_write);
710 if (!is_mute && payload_to_write > 0 && p_output_audio != nullptr){
711 p_synch->writeAudio(p_output_audio, parse_buffer.data(), payload_to_write);
712 }
713 open_subchunk_len -= to_write;
714 cleanupStack();
715 consume(to_write);
716 } else if (current_stream_data.isVideo()) {
717 LOGD("video %d", (int)to_write);
718 if (payload_to_write > 0) {
719 if (p_output_video != nullptr)
720 p_output_video->write(parse_buffer.data(), payload_to_write);
721 if (p_output_video_video != nullptr)
722 p_output_video_video->write(parse_buffer.data(), payload_to_write);
723 }
724 open_subchunk_len -= to_write;
725 cleanupStack();
726 consume(to_write);
727 }
728 }
729
730 // 'RIFF' fileSize fileType (data)
731 bool parseHeader() {
732 bool header_is_avi = false;
733 int headerSize = 12;
734 if (getStr(0, 4).equals("RIFF")) {
735 ParseObject result;
736 uint32_t header_file_size = getInt(4);
737 // chunk_size = file_size - 8; treat a near-max value (unbounded/
738 // streamed placeholder, mirroring WAVHeader's own convention) as
739 // "unknown" rather than wrapping around when normalizing to file_size
741 header_file_size >= 0xFFFFFFF0 ? 0 : header_file_size + 8;
742 header_is_avi = getStr(8, 4).equals("AVI ");
743 result.set(current_pos, "AVI ", header_file_size, AVIChunk);
744 processStack(result);
745 consume(headerSize);
746
747 } else {
748 LOGE("parseHeader");
749 }
750 return header_is_avi;
751 }
752
756 ParseObject result;
757 result.set(current_pos, getStr(0, 4), 0, AVIChunk);
758 return result;
759 }
760
763 ParseObject tryParseChunk(const char *id) {
764 ParseObject result;
765 if (getStr(0, 4).equals(id)) {
766 result.set(current_pos, id, 0, AVIChunk);
767 }
768 return result;
769 }
770
771 ParseObject tryParseList(const char *id) {
772 ParseObject result;
773 StrView &list_id = getStr(8, 4);
774 if (list_id.equals(id) && getStr(0, 3).equals("LIST")) {
775 result.set(current_pos, getStr(8, 4), getInt(4), AVIList);
776 }
777 return result;
778 }
779
782 ParseObject result;
783 if (getStr(0, 4).equals("LIST")) {
784 result.set(current_pos, getStr(8, 4), getInt(4), AVIList);
785 }
786 return result;
787 }
788
790 ParseObject parseChunk(const char *id) {
791 ParseObject result;
792 int chunk_size = getInt(4);
793 if (getStr(0, 4).equals(id) && parse_buffer.size() >= chunk_size) {
794 result.set(current_pos, id, chunk_size, AVIChunk);
795 processStack(result);
797 }
798 return result;
799 }
800
802 ParseObject parseList(const char *id) {
803 ParseObject result;
804 if (getStr(0, 4).equals("LIST") && getStr(8, 4).equals(id)) {
805 int size = getInt(4);
806 result.set(current_pos, id, size, AVIList);
807 processStack(result);
809 }
810 return result;
811 }
812
814 ParseObject result;
815 int size = getInt(4);
816 result.set(current_pos, getStr(0, 4), size, AVIStreamData);
817 if (result.isValid()) {
818 processStack(result);
819 consume(8);
820 }
821 return result;
822 }
823
824 void processStack(ParseObject &result) {
825 cleanupStack();
826 object_stack.push(result);
827 spaces.setChars(' ', object_stack.size());
828 LOGD("%s - %s (%d-%d) size:%d", spaces.c_str(), result.id(),
829 (int)result.start_pos, (int)result.end_pos, (int)result.data_size);
830 }
831
833 ParseObject current;
834 // make sure that we remove the object from the stack of we past the end
835 object_stack.peek(current);
836 while (current.end_pos <= current_pos) {
837 object_stack.pop(current);
838 object_stack.peek(current);
839 }
840 }
841
843 StrView &getStr(int offset, int len) {
844 str.setCapacity(len + 1);
845 const char *data = (const char *)parse_buffer.data();
846 str.copyFrom((data + offset), len, 5);
847
848 return str;
849 }
850
852 uint32_t getInt(int offset) {
853 uint32_t *result = (uint32_t *)(parse_buffer.data() + offset);
854 return *result;
855 }
856
858 void consume(int len) {
859 current_pos += len;
861 }
862};
863
866
906class MuxerAVI : public Muxer {
907 public:
909 MuxerAVI(Print &out) : MuxerAVI() { setOutput(out); }
910
911 const char *mime() override { return "video/avi"; }
912
914 void setOutput(Print &out) override { p_out = &out; }
915
917 void setVideoInfo(MuxerVideoConfig config) override { video_cfg = config; }
918
922
928 void setAudioInfo(AudioInfoFormat info) override {
929 audio_info = info;
930 has_audio = true;
931 }
933 AudioInfoFormat &audioInfo() override { return audio_info; }
934
937 bool begin() override {
938 if (p_out == nullptr) {
939 LOGE("output not defined");
940 return false;
941 }
942 if (video_cfg.width == 0 || video_cfg.height == 0) {
943 LOGE("invalid video size: %d x %d", (int)video_cfg.width,
944 (int)video_cfg.height);
945 return false;
946 }
947 writeHeader();
950 frame_open = false;
951 is_open = true;
952 return true;
953 }
954
958 void setStreamType(StreamContentType type) override { write_stream_type = type; }
961
963 void end() override { is_open = false; }
964
965 operator bool() override { return is_open; }
966
971 void beginFrame(size_t size) {
972 if (!is_open) return;
973 writeChunkHeader("00dc", (uint32_t)size);
974 frame_open = true;
975 frame_remaining = size;
976 frame_pad = (size % 2) != 0;
977 }
978
984 size_t writeFrame(const uint8_t *data, size_t len) {
985 if (!is_open || !frame_open) return 0;
986 size_t to_write = len < frame_remaining ? len : frame_remaining;
987 size_t written = p_out->write(data, to_write);
988 frame_remaining -= written;
989 return written;
990 }
991
993 uint32_t endFrame() {
994 if (frame_open && frame_pad) p_out->write((uint8_t)0);
995 frame_open = false;
997 return 0;
998 }
999
1007 size_t write(const uint8_t *data, size_t len) override {
1009 return addAudioFrame(data, len);
1010 }
1011 switch (video_cfg.format) {
1012 case VideoFormat::MJPEG:
1013 return addJpegFrame(data, len);
1015 return addYUV422Frame(data, len);
1017 return addRGB565Frame(data, len);
1018 case VideoFormat::I420:
1019 return addI420Frame(data, len);
1020 default:
1021 return addVideoFrame(data, len);
1022 }
1023 }
1024
1033 size_t addVideoFrame(const uint8_t *data, size_t len,
1034 bool isKeyFrame = true) override {
1035 beginFrame(len);
1036 size_t written = writeFrame(data, len);
1037 endFrame();
1038 return written;
1039 }
1040
1045 size_t addJpegFrame(const uint8_t *data, size_t len) override {
1047 return addVideoFrame(data, len);
1048 }
1049
1052 size_t addYUV422Frame(const uint8_t *data, size_t len) override {
1054 return addVideoFrame(data, len);
1055 }
1056
1059 size_t addRGB565Frame(const uint8_t *data, size_t len) override {
1061 return addVideoFrame(data, len);
1062 }
1063
1067 size_t addI420Frame(const uint8_t *data, size_t len) override {
1069 return addVideoFrame(data, len);
1070 }
1071
1074 size_t addAudioFrame(const uint8_t *data, size_t len) override {
1075 if (!is_open || !has_audio) return 0;
1076 writeChunkHeader("01wb", (uint32_t)len);
1077 size_t written = p_out->write(data, len);
1078 if (len % 2 != 0) p_out->write((uint8_t)0);
1080 return written;
1081 }
1082
1084 uint32_t videoFrameCount() { return video_frame_count; }
1086 uint32_t audioChunkCount() { return audio_chunk_count; }
1087
1088 protected:
1089 static const uint32_t AVIF_ISINTERLEAVED = 0x00000100;
1090
1091 Print *p_out = nullptr;
1095 bool has_audio = false;
1096 bool is_open = false;
1097 bool frame_open = false;
1098 bool frame_pad = false;
1100 uint32_t video_frame_count = 0;
1101 uint32_t audio_chunk_count = 0;
1102
1103 const char *fourCC() {
1104 if (video_cfg.fourcc != nullptr) return video_cfg.fourcc;
1105 switch (video_cfg.format) {
1106 case VideoFormat::H264:
1107 return "H264";
1108 case VideoFormat::MJPEG:
1109 return "MJPG";
1110 case VideoFormat::MPEG4:
1111 return "FMP4";
1112 case VideoFormat::RAW:
1113 return "DIB ";
1115 return "YUY2";
1117 return "RGBP";
1118 case VideoFormat::I420:
1119 return "I420";
1121 return "H264";
1122 }
1123 return "H264";
1124 }
1125
1129
1132 uint16_t biBitCount() {
1133 switch (video_cfg.format) {
1134 case VideoFormat::RAW:
1135 return 24;
1138 return 16;
1139 case VideoFormat::I420:
1140 return 12;
1141 default:
1142 return 24;
1143 }
1144 }
1145
1150 size_t px = (size_t)video_cfg.width * (size_t)video_cfg.height;
1151 switch (format) {
1152 case VideoFormat::RAW:
1153 return px * 3;
1156 return px * 2;
1157 case VideoFormat::I420:
1158 return px + px / 2;
1159 default:
1160 return 0;
1161 }
1162 }
1163
1166 uint32_t biSizeImage() { return (uint32_t)expectedRawFrameSize(video_cfg.format); }
1167
1172 writeU32(0); // BI_RGB
1173 } else if (video_cfg.format == VideoFormat::RGB565) {
1174 writeU32(3); // BI_BITFIELDS
1175 } else {
1176 writeFourCC(fourCC()); // e.g. H264, MJPG, FMP4, YUY2, I420
1177 }
1178 }
1179
1183 if (video_cfg.format != expected) {
1184 LOGW("getVideoInfo().format does not match the addXxxFrame() called");
1185 }
1186 }
1187
1190 void checkRawFrame(VideoFormat expected, size_t len) {
1191 checkVideoFormat(expected);
1192 size_t expected_size = expectedRawFrameSize(expected);
1193 if (expected_size > 0 && len != expected_size) {
1194 LOGW("frame size %d does not match the expected %d bytes for %d x %d",
1195 (int)len, (int)expected_size, (int)video_cfg.width,
1196 (int)video_cfg.height);
1197 }
1198 }
1199
1200 void writeU8(uint8_t v) { p_out->write(v); }
1201 void writeU16(uint16_t v) {
1202 uint8_t b[2] = {(uint8_t)(v & 0xFF), (uint8_t)((v >> 8) & 0xFF)};
1203 p_out->write(b, 2);
1204 }
1205 void writeI16(int16_t v) { writeU16((uint16_t)v); }
1206 void writeU32(uint32_t v) {
1207 uint8_t b[4] = {(uint8_t)(v & 0xFF), (uint8_t)((v >> 8) & 0xFF),
1208 (uint8_t)((v >> 16) & 0xFF), (uint8_t)((v >> 24) & 0xFF)};
1209 p_out->write(b, 4);
1210 }
1211 void writeFourCC(const char *cc) { p_out->write((const uint8_t *)cc, 4); }
1212 void writeZeros(int n) {
1213 for (int j = 0; j < n; j++) writeU8(0);
1214 }
1215 void writeChunkHeader(const char *id, uint32_t size) {
1216 writeFourCC(id);
1217 writeU32(size);
1218 }
1219
1222 uint32_t videoStrfSize() { return 40 + (isBitfields() ? 12 : 0); }
1223
1226 uint32_t videoStrlSize() { return 4 + (8 + 56) + (8 + videoStrfSize()); }
1229 uint32_t audioStrlSize() { return 4 + (8 + 56) + (8 + 18); }
1230
1232 uint32_t micros_per_frame =
1233 video_cfg.fps > 0 ? (uint32_t)(1000000.0f / video_cfg.fps) : 0;
1234 writeChunkHeader("avih", 56);
1235 writeU32(micros_per_frame); // dwMicroSecPerFrame
1236 writeU32(0); // dwMaxBytesPerSec
1237 writeU32(0); // dwPaddingGranularity
1238 writeU32(has_audio ? AVIF_ISINTERLEAVED : 0); // dwFlags
1239 writeU32(0); // dwTotalFrames (unknown)
1240 writeU32(0); // dwInitialFrames
1241 writeU32(has_audio ? 2 : 1); // dwStreams
1242 writeU32(0); // dwSuggestedBufferSize
1243 writeU32(video_cfg.width); // dwWidth
1244 writeU32(video_cfg.height); // dwHeight
1245 writeZeros(16); // dwReserved[4]
1246 }
1247
1249 writeFourCC("LIST");
1251 writeFourCC("strl");
1252
1253 // strh (AVIStreamHeader)
1254 writeChunkHeader("strh", 56);
1255 writeFourCC("vids");
1257 writeU32(0); // dwFlags
1258 writeU16(0); // wPriority
1259 writeU16(0); // wLanguage
1260 writeU32(0); // dwInitialFrames
1261 writeU32(1000); // dwScale
1262 writeU32((uint32_t)(video_cfg.fps * 1000)); // dwRate
1263 writeU32(0); // dwStart
1264 writeU32(0); // dwLength (unknown)
1265 writeU32(0); // dwSuggestedBufferSize
1266 writeU32(0xFFFFFFFF); // dwQuality (use default)
1267 writeU32(0); // dwSampleSize (variable per frame)
1268 writeI16(0); // rcFrame.left
1269 writeI16(0); // rcFrame.top
1270 writeI16((int16_t)video_cfg.width); // rcFrame.right
1271 writeI16((int16_t)video_cfg.height); // rcFrame.bottom
1272
1273 // strf (BITMAPINFOHEADER [+ 3 DWORD color masks for RGB565])
1275 writeU32(40); // biSize (base header; masks, if any, follow)
1276 writeU32(video_cfg.width); // biWidth
1277 writeU32(video_cfg.height); // biHeight
1278 writeU16(1); // biPlanes
1279 writeU16(biBitCount()); // biBitCount
1280 writeBiCompression(); // biCompression
1281 writeU32(biSizeImage()); // biSizeImage
1282 writeU32(0); // biXPelsPerMeter
1283 writeU32(0); // biYPelsPerMeter
1284 writeU32(0); // biClrUsed
1285 writeU32(0); // biClrImportant
1286 if (isBitfields()) {
1287 writeU32(0x0000F800); // red mask
1288 writeU32(0x000007E0); // green mask
1289 writeU32(0x0000001F); // blue mask
1290 }
1291 }
1292
1294 writeFourCC("LIST");
1296 writeFourCC("strl");
1297
1298 uint16_t block_align =
1299 (uint16_t)(audio_info.channels * (audio_info.bits_per_sample / 8));
1300 uint32_t byte_rate = (uint32_t)audio_info.sample_rate * block_align;
1301
1302 // strh (AVIStreamHeader)
1303 writeChunkHeader("strh", 56);
1304 writeFourCC("auds");
1305 writeZeros(4); // fccHandler (unspecified)
1306 writeU32(0); // dwFlags
1307 writeU16(0); // wPriority
1308 writeU16(0); // wLanguage
1309 writeU32(0); // dwInitialFrames
1310 writeU32(1); // dwScale
1311 writeU32((uint32_t)audio_info.sample_rate); // dwRate
1312 writeU32(0); // dwStart
1313 writeU32(0); // dwLength (unknown)
1314 writeU32(0); // dwSuggestedBufferSize
1315 writeU32(0xFFFFFFFF); // dwQuality
1316 writeU32(block_align); // dwSampleSize
1317 writeZeros(8); // rcFrame (unused for audio)
1318
1319 // strf (WAVEFORMATEX)
1320 writeChunkHeader("strf", 18);
1321 writeU16((uint16_t)audio_info.format); // wFormatTag
1322 writeU16(audio_info.channels); // nChannels
1323 writeU32((uint32_t)audio_info.sample_rate); // nSamplesPerSec
1324 writeU32(byte_rate); // nAvgBytesPerSec
1325 writeU16(block_align); // nBlockAlign
1326 writeU16(audio_info.bits_per_sample); // wBitsPerSample
1327 writeU16(0); // cbSize
1328 }
1329
1331 // hdrl LIST payload: "hdrl" FOURCC + avih chunk + strl LIST(s), each incl
1332 // their own headers
1333 uint32_t hdrl_size = 4 + (8 + 56) + (8 + videoStrlSize());
1334 if (has_audio) hdrl_size += (8 + audioStrlSize());
1335
1336 writeFourCC("RIFF");
1337 writeU32(0xFFFFFFFF); // total file size: unknown while streaming
1338 writeFourCC("AVI ");
1339
1340 writeFourCC("LIST");
1341 writeU32(hdrl_size);
1342 writeFourCC("hdrl");
1346
1347 writeFourCC("LIST");
1348 writeU32(0xFFFFFFFF); // movi size: unknown while streaming
1349 writeFourCC("movi");
1350 }
1351};
1352
1353} // namespace audio_tools
WAV Audio Formats used by Microsoft e.g. in AVI video files.
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define LIST_HEADER_SIZE
Definition ContainerAVI.h:11
#define CHUNK_HEADER_SIZE
Definition ContainerAVI.h:12
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
virtual void flush()
Definition Arduino.h:130
AudioInfo info
Definition AudioCodecsBase.h:77
void notifyAudioChange(AudioInfo info)
Definition AudioTypes.h:174
AVI Container Decoder which can be fed with small chunks of data. The minimum length must be bigger t...
Definition ContainerAVI.h:269
virtual size_t write(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:336
BitmapInfoHeader video_info
Definition ContainerAVI.h:431
long video_frame_start_ms
Definition ContainerAVI.h:439
void setupVideoInfo()
Definition ContainerAVI.h:656
bool parse()
Definition ContainerAVI.h:469
StrView & getStr(int offset, int len)
Provides the string at the indicated byte offset with the indicated length.
Definition ContainerAVI.h:843
void setMute(bool mute)
Definition ContainerAVI.h:327
ParseObject parseList(const char *id)
We load the indicated list from the current data.
Definition ContainerAVI.h:802
Str str
Definition ContainerAVI.h:444
AVIMainHeader main_header
Definition ContainerAVI.h:428
long current_pos
Definition ContainerAVI.h:441
ParseObject current_stream_data
Definition ContainerAVI.h:435
void setVideoAudioSync(VideoAudioSync *yourSync)
Replace the synchronization logic with your implementation.
Definition ContainerAVI.h:421
void setupAudioInfo()
Definition ContainerAVI.h:625
ParseObject parseChunk(const char *id)
We load the indicated chunk from the current data.
Definition ContainerAVI.h:790
Print * p_output_audio
Definition ContainerAVI.h:436
WAVFormatX audio_info
Definition ContainerAVI.h:432
bool(* validation_cb)(DemuxerAVI &avi)
Definition ContainerAVI.h:447
VideoOutput * p_output_video_video
Definition ContainerAVI.h:438
VideoInfo getVideoInfo() override
Definition ContainerAVI.h:381
bool send_wav_header
Definition ContainerAVI.h:449
AudioInfoFormat getAudioInfo() override
Definition ContainerAVI.h:403
Print * p_output_video
Definition ContainerAVI.h:437
VideoAudioSync * p_synch
Definition ContainerAVI.h:458
void end() override
Definition ContainerAVI.h:359
long open_subchunk_len
Definition ContainerAVI.h:440
int videoSeconds()
Provide the length of the video in seconds.
Definition ContainerAVI.h:418
void setOutputVideo(VideoOutput &out_stream)
Definition ContainerAVI.h:332
ParseObject tryParseList(const char *id)
Definition ContainerAVI.h:771
bool is_parsing_active
Definition ContainerAVI.h:425
void sendWavHeader()
Definition ContainerAVI.h:642
bool is_mute
Definition ContainerAVI.h:448
bool is_metadata_ready
Definition ContainerAVI.h:446
AVIMainHeader aviMainHeader()
Provides the information from the main header chunk.
Definition ContainerAVI.h:362
uint32_t getInt(int offset)
Provides the int32 at the indicated byte offset.
Definition ContainerAVI.h:852
bool is_wav_header_sent
Definition ContainerAVI.h:451
char video_format[5]
Definition ContainerAVI.h:445
int stream_header_idx
Definition ContainerAVI.h:429
ParseObject tryParseList()
We try to parse the actual state for any list.
Definition ContainerAVI.h:781
Stack< ParseObject > object_stack
Definition ContainerAVI.h:434
long movi_end_pos
Definition ContainerAVI.h:442
void cleanupStack()
Definition ContainerAVI.h:832
Vector< AVIStreamHeader > stream_header
Definition ContainerAVI.h:430
bool isMetadataReady()
Returns true if all metadata has been parsed and is available.
Definition ContainerAVI.h:410
ParseObject parseAVIStreamData()
Definition ContainerAVI.h:813
virtual void setOutputVideo(Print &out_stream) override
Definition ContainerAVI.h:329
Str spaces
Definition ContainerAVI.h:443
bool isCurrentStreamAudio()
Definition ContainerAVI.h:460
BitmapInfoHeader aviVideoInfo()
Provides the video information.
Definition ContainerAVI.h:368
const char * mime() override
The container's MIME type (e.g. "video/avi", "video/mp4").
Definition ContainerAVI.h:283
void consume(int len)
We remove the processed bytes from the beginning of the buffer.
Definition ContainerAVI.h:858
int video_seconds
Definition ContainerAVI.h:456
void setSendWavHeader(bool flag) override
Definition ContainerAVI.h:293
bool begin() override
Definition ContainerAVI.h:298
bool isCurrentStreamVideo()
Definition ContainerAVI.h:464
virtual void setOutput(Print &out_stream) override
Definition ContainerAVI.h:322
void writeData()
Definition ContainerAVI.h:697
Vector< StreamContentType > content_types
Definition ContainerAVI.h:433
bool header_is_avi
Definition ContainerAVI.h:424
uint32_t riff_file_size
Definition ContainerAVI.h:455
bool parseHeader()
Definition ContainerAVI.h:731
ParseObject tryParseChunk()
Definition ContainerAVI.h:755
ParseBuffer parse_buffer
Definition ContainerAVI.h:427
bool send_wav_header_explicit
Definition ContainerAVI.h:450
WAVFormatX aviAudioInfo()
Provides the audio information.
Definition ContainerAVI.h:373
VideoAudioSync defaultSynch
Definition ContainerAVI.h:457
void setOutputAudio(Print &out_stream) override
Definition ContainerAVI.h:314
const char * aviVideoFormat()
Definition ContainerAVI.h:370
AVIStreamHeader aviStreamHeader(int idx)
Provides the information from the stream header chunks.
Definition ContainerAVI.h:365
static VideoFormat toVideoFormat(uint32_t biCompression, uint16_t biBitCount)
Definition ContainerAVI.h:671
ParseObject tryParseChunk(const char *id)
Definition ContainerAVI.h:763
ParseState parse_state
Definition ContainerAVI.h:426
void setValidationCallback(bool(*cb)(DemuxerAVI &avi))
Definition ContainerAVI.h:413
void processStack(ParseObject &result)
Definition ContainerAVI.h:824
DemuxerAVI(int bufferSize=1024)
Definition ContainerAVI.h:279
Common interface for demuxers (DemuxerAVI, DemuxerMP4) that split a container's video and (optional) ...
Definition ContainerCommon.h:164
Configuration for the (single) video track written by MuxerAVI.
Definition ContainerAVI.h:906
StreamContentType write_stream_type
Definition ContainerAVI.h:1093
bool is_open
Definition ContainerAVI.h:1096
void setOutput(Print &out) override
Defines the output: e.g. a local File or a network Client.
Definition ContainerAVI.h:914
bool isBitfields()
Definition ContainerAVI.h:1128
void writeI16(int16_t v)
Definition ContainerAVI.h:1205
uint32_t videoStrfSize()
Definition ContainerAVI.h:1222
bool frame_pad
Definition ContainerAVI.h:1098
void writeBiCompression()
Definition ContainerAVI.h:1170
uint32_t biSizeImage()
Definition ContainerAVI.h:1166
size_t addVideoFrame(const uint8_t *data, size_t len, bool isKeyFrame=true) override
Definition ContainerAVI.h:1033
AudioInfoFormat audio_info
Definition ContainerAVI.h:1094
void writeU8(uint8_t v)
Definition ContainerAVI.h:1200
StreamContentType streamType() override
The track write() currently targets (see setStreamType())
Definition ContainerAVI.h:960
size_t addJpegFrame(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:1045
void writeHeader()
Definition ContainerAVI.h:1330
void checkVideoFormat(VideoFormat expected)
Definition ContainerAVI.h:1182
MuxerAVI(Print &out)
Definition ContainerAVI.h:909
void writeFourCC(const char *cc)
Definition ContainerAVI.h:1211
void checkRawFrame(VideoFormat expected, size_t len)
Definition ContainerAVI.h:1190
bool has_audio
Definition ContainerAVI.h:1095
bool frame_open
Definition ContainerAVI.h:1097
void beginFrame(size_t size)
Definition ContainerAVI.h:971
AudioInfoFormat & audioInfo() override
Provides read/write access to the audio track's AudioInfoFormat.
Definition ContainerAVI.h:933
uint32_t audioStrlSize()
Definition ContainerAVI.h:1229
void end() override
Closes the encoder: no trailer is written (streaming AVI has no idx1)
Definition ContainerAVI.h:963
size_t writeFrame(const uint8_t *data, size_t len)
Definition ContainerAVI.h:984
void writeU32(uint32_t v)
Definition ContainerAVI.h:1206
void setVideoInfo(MuxerVideoConfig config) override
Defines the video track configuration - call before begin()
Definition ContainerAVI.h:917
void setStreamType(StreamContentType type) override
Definition ContainerAVI.h:958
uint32_t endFrame()
Closes the current video frame (word-aligns the chunk)
Definition ContainerAVI.h:993
size_t addAudioFrame(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:1074
size_t write(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:1007
size_t frame_remaining
Definition ContainerAVI.h:1099
void writeAudioStrl()
Definition ContainerAVI.h:1293
void setAudioInfo(AudioInfoFormat info) override
Definition ContainerAVI.h:928
uint32_t videoFrameCount()
Number of video frames written so far.
Definition ContainerAVI.h:1084
size_t expectedRawFrameSize(VideoFormat format)
Definition ContainerAVI.h:1149
uint32_t audioChunkCount()
Number of audio chunks written so far.
Definition ContainerAVI.h:1086
size_t addYUV422Frame(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:1052
uint32_t audio_chunk_count
Definition ContainerAVI.h:1101
size_t addI420Frame(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:1067
MuxerAVI()
Definition ContainerAVI.h:908
Print * p_out
Definition ContainerAVI.h:1091
uint32_t videoStrlSize()
Definition ContainerAVI.h:1226
size_t addRGB565Frame(const uint8_t *data, size_t len) override
Definition ContainerAVI.h:1059
const char * mime() override
Definition ContainerAVI.h:911
void writeVideoStrl()
Definition ContainerAVI.h:1248
const char * fourCC()
Definition ContainerAVI.h:1103
bool begin() override
Definition ContainerAVI.h:937
void writeU16(uint16_t v)
Definition ContainerAVI.h:1201
void writeChunkHeader(const char *id, uint32_t size)
Definition ContainerAVI.h:1215
uint16_t biBitCount()
Definition ContainerAVI.h:1132
uint32_t video_frame_count
Definition ContainerAVI.h:1100
void writeZeros(int n)
Definition ContainerAVI.h:1212
void writeMainHeader()
Definition ContainerAVI.h:1231
MuxerVideoConfig getVideoInfo() override
Definition ContainerAVI.h:921
MuxerVideoConfig video_cfg
Definition ContainerAVI.h:1092
static const uint32_t AVIF_ISINTERLEAVED
Definition ContainerAVI.h:1089
Common interface for muxers (MuxerAVI, MuxerMP4) that combine an already-encoded video track (and opt...
Definition ContainerCommon.h:42
We try to keep the necessary buffer for parsing as small as possible, The data() method provides the ...
Definition ContainerAVI.h:23
Vector< uint8_t > vector
Definition ContainerAVI.h:67
size_t size()
Definition ContainerAVI.h:58
size_t writeArray(uint8_t *data, size_t len)
Definition ContainerAVI.h:25
size_t availableToWrite()
Definition ContainerAVI.h:47
size_t available_byte_count
Definition ContainerAVI.h:68
void consume(int size)
Definition ContainerAVI.h:31
size_t available()
Definition ContainerAVI.h:49
uint8_t * data()
Definition ContainerAVI.h:45
long indexOf(const char *str)
Definition ContainerAVI.h:60
void clear()
Definition ContainerAVI.h:51
bool resize(size_t size)
Definition ContainerAVI.h:40
bool isEmpty()
Definition ContainerAVI.h:56
Represents a LIST or a CHUNK: The ParseObject represents the current parsing result....
Definition ContainerAVI.h:170
size_t size()
Definition ContainerAVI.h:195
bool isVideo()
Definition ContainerAVI.h:249
size_t open
Definition ContainerAVI.h:224
size_t end_pos
Definition ContainerAVI.h:225
WAVFormatX * asAVIAudioFormat(void *ptr)
Definition ContainerAVI.h:219
size_t start_pos
Definition ContainerAVI.h:226
ParseObjectType type()
Definition ContainerAVI.h:201
bool isVideoCompressed()
Definition ContainerAVI.h:244
void set(size_t currentPos, const char *id, size_t size, ParseObjectType type)
Definition ContainerAVI.h:176
char chunk_id[5]
Definition ContainerAVI.h:253
size_t declared_size
Definition ContainerAVI.h:228
ParseObjectType object_type
Definition ContainerAVI.h:254
size_t declaredSize()
Definition ContainerAVI.h:199
BitmapInfoHeader * asVideoFormat(void *ptr)
Definition ContainerAVI.h:220
void set(size_t currentPos, StrView id, size_t size, ParseObjectType type)
Definition ContainerAVI.h:172
int streamNumber()
Definition ContainerAVI.h:231
AVIMainHeader * asAVIMainHeader(void *ptr)
Definition ContainerAVI.h:215
bool isVideoUncompressed()
Definition ContainerAVI.h:239
size_t data_size
Definition ContainerAVI.h:227
bool isAudio()
Definition ContainerAVI.h:234
AVIStreamHeader * asAVIStreamHeader(void *ptr)
Definition ContainerAVI.h:216
const char * id()
Definition ContainerAVI.h:194
bool isValid()
Definition ContainerAVI.h:202
LIFO Stack which is based on a List.
Definition Stack.h:14
Str which keeps the data on the heap. We grow the allocated memory only if the copy source is not fit...
Definition Str.h:24
void copyFrom(const char *source, int len, int maxlen=0)
assigns a memory buffer
Definition Str.h:96
void setCapacity(size_t newLen)
Definition Str.h:86
void setChars(char c, int len)
Fills the string with len chars.
Definition Str.h:108
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:28
virtual bool equals(const char *str)
checks if the string equals indicated parameter string
Definition StrView.h:165
virtual const char * c_str()
provides the string value as const char*
Definition StrView.h:380
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
void push_back(T &&value)
Definition Vector.h:182
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
Logic to Synchronize video and audio output: This is the minimum implementatin which actually does no...
Definition Video.h:211
virtual void delayVideoFrame(int32_t microsecondsPerFrame, uint32_t time_used_ms)
Definition Video.h:220
virtual void writeAudio(Print *out, uint8_t *data, size_t size)
Process the audio data.
Definition Video.h:214
Abstract class for video playback. This class is used to assemble a complete video frame in memory....
Definition Video.h:192
virtual size_t write(const uint8_t *data, size_t len)=0
virtual void flush()
Definition Video.h:198
Parser for Wav header data for details see https://de.wikipedia.org/wiki/RIFF_WAVE.
Definition CodecWAV.h:78
void setAudioInfo(WAVAudioInfo info)
Sets the info in the header.
Definition CodecWAV.h:155
bool writeHeader(Print *out)
Just write a wav header to the indicated outputbu.
Definition CodecWAV.h:158
char[4] FOURCC
Four-character code identifier for AVI format.
Definition ContainerAVI.h:73
VideoFormat
Video codec/pixel-format identifier, shared by two unrelated uses: the (single) video stream of a con...
Definition Video.h:43
StreamContentType
Which track write() feeds, for muxers (MuxerAVI, MuxerMP4) that double as a plain,...
Definition Video.h:19
size_t videoFrameSizeBytes(VideoFormat format, uint16_t width, uint16_t height)
Fixed per-frame size (bytes) for a raw/uncompressed VideoFormat at the given resolution - 0 for compr...
Definition Video.h:61
AudioFormat
Audio format codes used by Microsoft e.g. in avi or wav files.
Definition AudioFormat.h:21
bool isWavFormat(AudioFormat format)
True if the wav code is handled via the WAV decoder (i.e. toMime() maps it to "audio/wav": PCM and al...
Definition AudioFormat.h:348
@ Audio
Definition Video.h:19
@ Video
Definition Video.h:19
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
ParseObjectType
Definition ContainerAVI.h:148
@ AVIChunk
Definition ContainerAVI.h:148
@ AVIList
Definition ContainerAVI.h:148
@ AVIStreamData
Definition ContainerAVI.h:148
ParseState
Definition ContainerAVI.h:150
@ ParseStrl
Definition ContainerAVI.h:154
@ ParseStrf
Definition ContainerAVI.h:158
@ AfterStrf
Definition ContainerAVI.h:159
@ SubChunkContinue
Definition ContainerAVI.h:155
@ ParseMovi
Definition ContainerAVI.h:160
@ SubChunk
Definition ContainerAVI.h:156
@ ParseRec
Definition ContainerAVI.h:157
@ ParseHdrl
Definition ContainerAVI.h:152
@ ParseHeader
Definition ContainerAVI.h:151
@ ParseIgnore
Definition ContainerAVI.h:161
@ ParseAvih
Definition ContainerAVI.h:153
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:260
Definition ContainerAVI.h:75
uint32_t dwStreams
Definition ContainerAVI.h:84
uint32_t dwInitialFrames
Definition ContainerAVI.h:83
uint32_t dwMaxBytesPerSec
Definition ContainerAVI.h:79
uint32_t dwHeight
Definition ContainerAVI.h:87
uint32_t dwReserved[4]
Definition ContainerAVI.h:88
uint32_t dwFlags
Definition ContainerAVI.h:81
uint32_t dwPaddingGranularity
Definition ContainerAVI.h:80
uint32_t dwMicroSecPerFrame
Definition ContainerAVI.h:78
uint32_t dwSuggestedBufferSize
Definition ContainerAVI.h:85
uint32_t dwWidth
Definition ContainerAVI.h:86
uint32_t dwTotalFrames
Definition ContainerAVI.h:82
Definition ContainerAVI.h:96
uint32_t dwSampleSize
Definition ContainerAVI.h:109
uint32_t dwLength
Definition ContainerAVI.h:106
uint32_t dwInitialFrames
Definition ContainerAVI.h:102
uint16_t wPriority
Definition ContainerAVI.h:100
uint16_t wLanguage
Definition ContainerAVI.h:101
FOURCC fccType
Definition ContainerAVI.h:97
uint32_t dwScale
Definition ContainerAVI.h:103
FOURCC fccHandler
Definition ContainerAVI.h:98
uint32_t dwFlags
Definition ContainerAVI.h:99
uint32_t dwStart
Definition ContainerAVI.h:105
uint32_t dwQuality
Definition ContainerAVI.h:108
RECT rcFrame
Definition ContainerAVI.h:110
uint32_t dwRate
Definition ContainerAVI.h:104
uint32_t dwSuggestedBufferSize
Definition ContainerAVI.h:107
AudioInfo extended with a WAVEFORMATEX-style codec tag (the "wav code"): identifies the codec (PCM,...
Definition AudioFormat.h:389
AudioFormat format
Definition AudioFormat.h:398
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
virtual void logInfo(const char *source="")
Definition AudioTypes.h:121
Definition ContainerAVI.h:116
uint32_t biSizeImage
Definition ContainerAVI.h:123
uint32_t biCompression
Definition ContainerAVI.h:122
uint32_t biWidth
Definition ContainerAVI.h:118
uint16_t biBitCount
Definition ContainerAVI.h:121
uint32_t biHeight
Definition ContainerAVI.h:119
uint32_t biYPelsPerMeter
Definition ContainerAVI.h:125
uint32_t biClrImportant
Definition ContainerAVI.h:127
uint32_t biSize
Definition ContainerAVI.h:117
uint16_t biPlanes
Definition ContainerAVI.h:120
uint32_t biClrUsed
Definition ContainerAVI.h:126
uint32_t biXPelsPerMeter
Definition ContainerAVI.h:124
Shared video track configuration for muxers (MuxerAVI, MuxerMP4) - call before begin().
Definition ContainerCommon.h:11
float fps
Definition ContainerCommon.h:14
const char * fourcc
Definition ContainerCommon.h:20
uint16_t height
Definition ContainerCommon.h:13
uint16_t width
Definition ContainerCommon.h:12
VideoFormat format
Definition ContainerCommon.h:15
Definition ContainerAVI.h:91
uint32_t dwHeight
Definition ContainerAVI.h:93
uint32_t dwWidth
Definition ContainerAVI.h:92
Basic video information (width/height/codec/frame size), analogous to AudioInfo - common to both Demu...
Definition Video.h:102
uint32_t frame_size
Definition Video.h:115
uint32_t total_file_size
Definition Video.h:121
uint16_t height
Frame height in pixels.
Definition Video.h:106
uint16_t width
Frame width in pixels.
Definition Video.h:104
VideoFormat format
Video codec - VideoFormat::UNKNOWN if not (yet) determined.
Definition Video.h:111
Sound information which is available in the WAV header.
Definition CodecWAV.h:30
AudioFormat format
Definition CodecWAV.h:38
bool is_streamed
Definition CodecWAV.h:41
int block_align
Definition CodecWAV.h:40
int byte_rate
Definition CodecWAV.h:39
bool ext_adpcm_header
write the extended 'fmt ' chunk + 'fact' chunk for ADPCM formats
Definition CodecWAV.h:47
Definition ContainerAVI.h:130
uint16_t wBitsPerSample
Definition ContainerAVI.h:136
uint16_t nChannels
Definition ContainerAVI.h:132
uint16_t nBlockAlign
Definition ContainerAVI.h:135
uint32_t nSamplesPerSec
Definition ContainerAVI.h:133
uint32_t nAvgBytesPerSec
Definition ContainerAVI.h:134
uint16_t cbSize
Definition ContainerAVI.h:137
AudioFormat wFormatTag
Definition ContainerAVI.h:131