]> git.sesse.net Git - nageru/blobdiff - mixer.cpp
Use the new decode_video_format() function from bmusb.
[nageru] / mixer.cpp
index db5980d2d79bbdf30d3b005bd3394644120309a3..1d1a60cdea8f96576d202730bfdf763f7deb0712 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -212,57 +212,6 @@ void deinterleave_samples(const vector<float> &in, vector<float> *out_l, vector<
        }
 }
 
-// Returns length of a frame with the given format, in TIMEBASE units.
-int64_t find_frame_length(uint16_t video_format)
-{
-       if (video_format == 0x0800) {
-               // No video signal. These green pseudo-frames seem to come at about 30.13 Hz.
-               // It's a strange thing, but what can you do.
-               return TIMEBASE * 100 / 3013;
-       }
-       if ((video_format & 0xe800) != 0xe800) {
-               printf("Video format 0x%04x does not appear to be a video format. Assuming 60 Hz.\n",
-                       video_format);
-               return TIMEBASE / 60;
-       }
-
-       // 0x8 seems to be a flag about availability of deep color on the input,
-       // except when it's not (e.g. it's the only difference between NTSC 23.98
-       // and PAL). Rather confusing. But we clear it here nevertheless, because
-       // usually it doesn't mean anything.
-       //
-       // We don't really handle interlaced formats at all yet.
-       uint16_t normalized_video_format = video_format & ~0xe808;
-       if (normalized_video_format == 0x0143) {         // 720p50.
-               return TIMEBASE / 50;
-       } else if (normalized_video_format == 0x0103) {  // 720p60.
-               return TIMEBASE / 60;
-       } else if (normalized_video_format == 0x0121) {  // 720p59.94.
-               return TIMEBASE * 1001 / 60000;
-       } else if (normalized_video_format == 0x01c3 ||  // 1080p30.
-                  normalized_video_format == 0x0003) {  // 1080i60.
-               return TIMEBASE / 30;
-       } else if (normalized_video_format == 0x01e1 ||  // 1080p29.97.
-                  normalized_video_format == 0x0021 ||  // 1080i59.94.
-                  video_format == 0xe901 ||             // NTSC (480i59.94, I suppose).
-                  video_format == 0xe9c1 ||             // Ditto.
-                  video_format == 0xe801) {             // Ditto.
-               return TIMEBASE * 1001 / 30000;
-       } else if (normalized_video_format == 0x0063 ||  // 1080p25.
-                  normalized_video_format == 0x0043 ||  // 1080i50.
-                  video_format == 0xe909) {             // PAL (576i50, I suppose).
-               return TIMEBASE / 25;
-       } else if (normalized_video_format == 0x008e) {  // 1080p24.
-               return TIMEBASE / 24;
-       } else if (normalized_video_format == 0x00a1) {  // 1080p23.98.
-               return TIMEBASE * 1001 / 24000;
-               return TIMEBASE / 25;
-       } else {
-               printf("Unknown video format 0x%04x. Assuming 60 Hz.\n", video_format);
-               return TIMEBASE / 60;
-       }
-}
-
 }  // namespace
 
 void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
@@ -271,9 +220,14 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
 {
        CaptureCard *card = &cards[card_index];
 
-       int64_t frame_length = find_frame_length(video_format);
+       int width, height, frame_rate_nom, frame_rate_den;
+       bool interlaced;
 
-       if (audio_frame.len - audio_offset > 30000) {
+       decode_video_format(video_format, &width, &height, &frame_rate_nom, &frame_rate_den, &interlaced);  // Ignore return value for now.
+       int64_t frame_length = TIMEBASE * frame_rate_den / frame_rate_nom;
+
+       size_t num_samples = (audio_frame.len >= audio_offset) ? (audio_frame.len - audio_offset) / 8 / 3 : 0;
+       if (num_samples > OUTPUT_FREQUENCY / 10) {
                printf("Card %d: Dropping frame with implausible audio length (len=%d, offset=%d) [timecode=0x%04x video_len=%d video_offset=%d video_format=%x)\n",
                        card_index, int(audio_frame.len), int(audio_offset),
                        timecode, int(video_frame.len), int(video_offset), video_format);
@@ -294,7 +248,6 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
        card->last_timecode = timecode;
 
        // Convert the audio to stereo fp32 and add it.
-       size_t num_samples = (audio_frame.len >= audio_offset) ? (audio_frame.len - audio_offset) / 8 / 3 : 0;
        vector<float> audio;
        audio.resize(num_samples * 2);
        convert_fixed24_to_fp32(&audio[0], 2, audio_frame.data + audio_offset, 8, num_samples);
@@ -410,7 +363,7 @@ void Mixer::thread_func()
        clock_gettime(CLOCK_MONOTONIC, &start);
 
        int frame = 0;
-       int dropped_frames = 0;
+       int stats_dropped_frames = 0;
 
        while (!should_quit) {
                CaptureCard card_copy[MAX_CARDS];
@@ -452,7 +405,7 @@ void Mixer::thread_func()
                                // For dropped frames, increase the pts. Note that if the format changed
                                // in the meantime, we have no way of detecting that; we just have to
                                // assume the frame length is always the same.
-                               ++dropped_frames;
+                               ++stats_dropped_frames;
                                pts_int += card_copy[0].new_frame_length;
                        }
                }
@@ -481,7 +434,7 @@ void Mixer::thread_func()
                // If the first card is reporting a corrupted or otherwise dropped frame,
                // just increase the pts (skipping over this frame) and don't try to compute anything new.
                if (card_copy[0].new_frame->len == 0) {
-                       ++dropped_frames;
+                       ++stats_dropped_frames;
                        pts_int += card_copy[0].new_frame_length;
                        continue;
                }
@@ -582,7 +535,7 @@ void Mixer::thread_func()
                        1e-9 * (now.tv_nsec - start.tv_nsec);
                if (frame % 100 == 0) {
                        printf("%d frames (%d dropped) in %.3f seconds = %.1f fps (%.1f ms/frame)\n",
-                               frame, dropped_frames, elapsed, frame / elapsed,
+                               frame, stats_dropped_frames, elapsed, frame / elapsed,
                                1e3 * elapsed / frame);
                //      chain->print_phase_timing();
                }