Welcome to mirror list, hosted at ThFree Co, Russian Federation.

scc_enc.rs « tests « closedcaption « video - gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b23e9d70a226bb772dee64d4375b38e11e7d8f4c (plain)
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
// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.com>
// Copyright (C) 2019 Jordan Petridis <jordan@centricular.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0

use pretty_assertions::assert_eq;

fn init() {
    use std::sync::Once;
    static INIT: Once = Once::new();

    INIT.call_once(|| {
        gst::init().unwrap();
        gstrsclosedcaption::plugin_register_static().unwrap();
    });
}

/// Encode a single raw CEA608 packet and compare the output
#[test]
fn test_encode_single_packet() {
    init();

    let input = [148, 44];
    let expected_output = b"Scenarist_SCC V1.0\r\n\r\n11:12:13;14\t942c\r\n\r\n";

    let mut h = gst_check::Harness::new("sccenc");
    h.set_src_caps_str("closedcaption/x-cea-608, format=raw, framerate=(fraction)30000/1001");
    let tc = gst_video::ValidVideoTimeCode::new(
        gst::Fraction::new(30000, 1001),
        None,
        gst_video::VideoTimeCodeFlags::DROP_FRAME,
        11,
        12,
        13,
        14,
        0,
    )
    .unwrap();

    let buf = {
        let mut buf = gst::Buffer::from_mut_slice(Vec::from(&input[..]));
        let buf_ref = buf.get_mut().unwrap();
        gst_video::VideoTimeCodeMeta::add(buf_ref, &tc);
        buf_ref.set_pts(gst::ClockTime::ZERO);
        buf
    };

    assert_eq!(h.push(buf), Ok(gst::FlowSuccess::Ok));
    h.push_event(gst::event::Eos::new());

    let buf = h.pull().expect("Couldn't pull buffer");

    let timecode = buf
        .meta::<gst_video::VideoTimeCodeMeta>()
        .expect("No timecode for buffer")
        .tc();
    assert_eq!(timecode, tc);

    let pts = buf.pts().unwrap();
    assert_eq!(pts, gst::ClockTime::ZERO);

    let map = buf.map_readable().expect("Couldn't map buffer readable");
    assert_eq!(
        std::str::from_utf8(map.as_ref()),
        std::str::from_utf8(expected_output.as_ref())
    );
}

/// Encode a multiple raw CEA608 packets and compare the output
#[test]
fn test_encode_multiple_packets() {
    init();

    let input1 = [148, 44];
    let input2 = [
        148, 32, 148, 32, 148, 174, 148, 174, 148, 84, 148, 84, 16, 174, 16, 174, 70, 242, 239,
        109, 32, 206, 229, 247, 32, 217, 239, 242, 107, 44, 148, 242, 148, 242, 16, 174, 16, 174,
        244, 104, 233, 115, 32, 233, 115, 32, 196, 229, 109, 239, 227, 242, 97, 227, 121, 32, 206,
        239, 247, 161, 148, 47, 148, 47,
    ];

    let expected_output1 = b"Scenarist_SCC V1.0\r\n\r\n00:00:00;00\t942c 942c\r\n\r\n";
    let expected_output2 = b"00:00:14;01\t9420 9420 94ae 94ae 9454 9454 10ae 10ae 46f2 ef6d 20ce e5f7 20d9 eff2 6b2c 94f2\r\n\r\n";
    let expected_output3 = b"00:00:14;17\t94f2 10ae 10ae f468 e973 20e9 7320 c4e5 6def e3f2 61e3 7920 ceef f7a1 942f 942f\r\n\r\n";

    let mut h = gst_check::Harness::new("sccenc");
    h.set_src_caps_str("closedcaption/x-cea-608, format=raw, framerate=(fraction)30000/1001");
    let tc1 = gst_video::ValidVideoTimeCode::new(
        gst::Fraction::new(30000, 1001),
        None,
        gst_video::VideoTimeCodeFlags::DROP_FRAME,
        0,
        0,
        0,
        0,
        0,
    )
    .unwrap();

    let tc2 = gst_video::ValidVideoTimeCode::new(
        gst::Fraction::new(30000, 1001),
        None,
        gst_video::VideoTimeCodeFlags::DROP_FRAME,
        0,
        0,
        14,
        1,
        0,
    )
    .unwrap();

    let buf1 = {
        let mut buf = gst::Buffer::from_mut_slice(Vec::from(&input1[..]));
        let buf_ref = buf.get_mut().unwrap();
        gst_video::VideoTimeCodeMeta::add(buf_ref, &tc1);
        buf_ref.set_pts(gst::ClockTime::ZERO);
        buf
    };

    let buf2 = {
        let mut buf = gst::Buffer::from_mut_slice(Vec::from(&input1[..]));
        let buf_ref = buf.get_mut().unwrap();
        let mut tc = tc1.clone();
        tc.increment_frame();
        gst_video::VideoTimeCodeMeta::add(buf_ref, &tc);
        buf_ref.set_pts(gst::ClockTime::ZERO);
        buf
    };

    let mut t = tc2.clone();
    let mut buffers = input2
        .chunks(2)
        .map(move |bytes| {
            let mut buf = gst::Buffer::from_mut_slice(Vec::from(bytes));
            let buf_ref = buf.get_mut().unwrap();
            gst_video::VideoTimeCodeMeta::add(buf_ref, &t);
            t.increment_frame();
            buf
        })
        .collect::<Vec<gst::Buffer>>();
    buffers.insert(0, buf1);
    buffers.insert(1, buf2);

    buffers.iter().for_each(|buf| {
        assert_eq!(h.push(buf.clone()), Ok(gst::FlowSuccess::Ok));
    });
    h.push_event(gst::event::Eos::new());

    // Pull 1
    let buf = h.pull().expect("Couldn't pull buffer");

    let timecode = buf
        .meta::<gst_video::VideoTimeCodeMeta>()
        .expect("No timecode for buffer")
        .tc();
    assert_eq!(timecode, tc1);

    let pts = buf.pts().unwrap();
    assert_eq!(pts, gst::ClockTime::ZERO);

    let map = buf.map_readable().expect("Couldn't map buffer readable");

    assert_eq!(
        std::str::from_utf8(map.as_ref()),
        std::str::from_utf8(expected_output1.as_ref())
    );

    // Pull 2
    let buf = h.pull().expect("Couldn't pull buffer");
    let timecode = buf
        .meta::<gst_video::VideoTimeCodeMeta>()
        .expect("No timecode for buffer")
        .tc();
    assert_eq!(timecode, tc2);

    // let pts = buf.get_pts().unwrap();
    // assert_eq!(pts, gst::ClockTime::ZERO);

    let map = buf.map_readable().expect("Couldn't map buffer readable");
    assert_eq!(
        std::str::from_utf8(map.as_ref()),
        std::str::from_utf8(expected_output2.as_ref())
    );

    let tc3 = gst_video::ValidVideoTimeCode::new(
        gst::Fraction::new(30000, 1001),
        None,
        gst_video::VideoTimeCodeFlags::DROP_FRAME,
        0,
        0,
        14,
        17,
        0,
    )
    .unwrap();

    // Pull 3
    let buf = h.pull().expect("Couldn't pull buffer");
    let timecode = buf
        .meta::<gst_video::VideoTimeCodeMeta>()
        .expect("No timecode for buffer")
        .tc();
    assert_eq!(timecode, tc3);

    // let pts = buf.get_pts().unwrap();
    // assert_eq!(pts, gst::ClockTime::ZERO);

    let map = buf.map_readable().expect("Couldn't map buffer readable");
    assert_eq!(
        std::str::from_utf8(map.as_ref()),
        std::str::from_utf8(expected_output3.as_ref())
    );
}