closedcaption: update to cea708-types 0.3

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1398>
This commit is contained in:
Matthew Waters 2023-11-07 17:19:01 +11:00
parent 5739a3d86f
commit d644bcd79a
4 changed files with 37 additions and 27 deletions

9
Cargo.lock generated
View file

@ -992,13 +992,14 @@ dependencies = [
[[package]] [[package]]
name = "cea708-types" name = "cea708-types"
version = "0.1.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a23ec736ab2aafb861ef6f22c662cbc18c85e73945f86bd9e936a20be7cc958" checksum = "ab4d26b125a97b4fdd73c45b64ec8d1c7e0d0dd12a25acec5ca98a38c400b66b"
dependencies = [ dependencies = [
"env_logger 0.10.1",
"log",
"muldiv",
"once_cell", "once_cell",
"tracing",
"tracing-subscriber",
] ]
[[package]] [[package]]

View file

@ -21,7 +21,7 @@ pangocairo = { git = "https://github.com/gtk-rs/gtk-rs-core" }
byteorder = "1" byteorder = "1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["raw_value"] } serde_json = { version = "1.0", features = ["raw_value"] }
cea708-types = "0.1" cea708-types = "0.3"
[dependencies.gst] [dependencies.gst]
git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"

View file

@ -7,6 +7,7 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use cea708_types::{tables::*, DTVCCPacket}; use cea708_types::{tables::*, DTVCCPacket};
use cea708_types::{CCDataWriter, Framerate};
use gst::glib; use gst::glib;
use gst::prelude::*; use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
@ -14,7 +15,7 @@ use gst::subclass::prelude::*;
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use crate::cea608utils::*; use crate::cea608utils::*;
use crate::cea708utils::{Cea708ServiceWriter, textstyle_foreground_color, textstyle_to_pen_color, Cea708ServiceWriter}; use crate::cea708utils::{textstyle_foreground_color, textstyle_to_pen_color, Cea708ServiceWriter};
use gst::glib::once_cell::sync::Lazy; use gst::glib::once_cell::sync::Lazy;
@ -193,17 +194,19 @@ impl Cea708ServiceState {
} }
if need_pen_attributes { if need_pen_attributes {
self.writer.set_pen_attributes(self.pen_attributes).unwrap(); self.writer.set_pen_attributes(self.pen_attributes);
} }
} }
fn carriage_return(&mut self) { fn carriage_return(&mut self) {
self.writer.carriage_return().unwrap(); self.writer.carriage_return();
} }
} }
struct Cea708State { struct Cea708State {
packet_counter: u8, packet_counter: u8,
writer: CCDataWriter,
framerate: Framerate,
service_state: [Cea708ServiceState; 4], service_state: [Cea708ServiceState; 4],
} }
@ -225,31 +228,32 @@ impl Cea708State {
} }
} }
} }
self.writer.push_packet(packet);
let mut cc_data = Vec::with_capacity(64);
assert!(s334_1a_data.len() % 3 == 0); assert!(s334_1a_data.len() % 3 == 0);
for triple in s334_1a_data.chunks(3) { for triple in s334_1a_data.chunks(3) {
if (triple[0] & 0x80) > 0 { if (triple[0] & 0x80) > 0 {
cc_data.push(0xfd); self.writer
.push_cea608(cea708_types::Cea608::Field1(triple[1], triple[2]))
} else { } else {
cc_data.push(0xfc); self.writer
.push_cea608(cea708_types::Cea608::Field2(triple[1], triple[2]))
} }
cc_data.extend(&triple[1..]);
} }
let mut ccp_data = Vec::with_capacity(128); let mut cc_data = Vec::with_capacity(128);
packet.write_cc_data(&mut ccp_data).ok()?; self.writer.write(self.framerate, &mut cc_data).unwrap();
gst::trace!( gst::trace!(
CAT, CAT,
"take_buffer produced cc_data_len:{} cc_data:{cc_data:?}", "take_buffer produced cc_data_len:{} cc_data:{cc_data:?}",
cc_data.len() cc_data.len()
); );
// ignore the 2 byte cc_data header that is unused in GStreamer if cc_data.len() > 2 {
if ccp_data.len() > 2 { // ignore the 2 byte cc_data header that is unused in GStreamer
cc_data.extend(&ccp_data[2..]); let cc_data = cc_data.split_off(2);
} else if cc_data.is_empty() { Some(gst::Buffer::from_slice(cc_data))
return None; } else {
None
} }
Some(gst::Buffer::from_slice(cc_data))
} }
} }
@ -264,6 +268,8 @@ impl Default for State {
cea608: Cea608State::default(), cea608: Cea608State::default(),
cea708: Cea708State { cea708: Cea708State {
packet_counter: 0, packet_counter: 0,
writer: CCDataWriter::default(),
framerate: Framerate::new(30, 1),
service_state: [ service_state: [
Cea708ServiceState::new(1), Cea708ServiceState::new(1),
Cea708ServiceState::new(2), Cea708ServiceState::new(2),
@ -618,14 +624,16 @@ impl Cea608ToCea708 {
return false; return false;
} }
}; };
let framerate = framerate.unwrap_or(gst::Fraction::new(30, 1));
state.cea708.framerate =
Framerate::new(framerate.numer() as u32, framerate.denom() as u32);
drop(state); drop(state);
let mut caps_builder = let caps = gst::Caps::builder("closedcaption/x-cea-708")
gst::Caps::builder("closedcaption/x-cea-708").field("format", "cc_data"); .field("format", "cc_data")
if let Some(framerate) = framerate { .field("framerate", framerate)
caps_builder = caps_builder.field("framerate", framerate); .build();
} let new_event = gst::event::Caps::new(&caps);
let new_event = gst::event::Caps::new(&caps_builder.build());
return self.srcpad.push_event(new_event); return self.srcpad.push_event(new_event);
} }

View file

@ -31,7 +31,7 @@ struct TestState {
impl TestState { impl TestState {
fn new() -> Self { fn new() -> Self {
let mut h = gst_check::Harness::new_parse("cea608tocea708"); let mut h = gst_check::Harness::new_parse("cea608tocea708");
h.set_src_caps_str("closedcaption/x-cea-608,format=raw,field=0"); h.set_src_caps_str("closedcaption/x-cea-608,format=raw,field=0,framerate=25/1");
h.set_sink_caps_str("closedcaption/x-cea-708,format=cc_data"); h.set_sink_caps_str("closedcaption/x-cea-708,format=cc_data");
Self { Self {
@ -98,6 +98,7 @@ fn test_single_char() {
caps, caps,
gst::Caps::builder("closedcaption/x-cea-708") gst::Caps::builder("closedcaption/x-cea-708")
.field("format", "cc_data") .field("format", "cc_data")
.field("framerate", gst::Fraction::new(25, 1))
.build() .build()
); );
} }