-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V380 Pro: bad sps #108
Comments
The camera uses the macro-media rtsp server #52. I made a test case based on the second set of packets in the Wireshark dump: https://github.com/Curid/retina/tree/issue108 |
gortsplib behavior:
retina behavior:
|
The SPS is valid after annexb decoding: h264_readeruse h264_reader::{
nal::sps::SeqParameterSet,
rbsp::{decode_nal, BitReader},
};
fn main() {
// hex: 274de0288d680a03da1000000300100000030280f1422a
let sps_rbsp = decode_nal(&[
39, 77, 224, 40, 141, 104, 10, 3, 218, 16, 0, 0, 3, 0, 16, 0, 0, 3, 2, 128, 241, 66, 42,
])
.unwrap();
let sps = SeqParameterSet::from_bits(BitReader::new(&*sps_rbsp)).unwrap();
println!("sps: {sps:#?}");
/*
sps: SeqParameterSet {
profile_idc: ProfileIdc(
77,
),
constraint_flags: ConstraintFlags {
flag0: true,
flag1: true,
flag2: true,
flag3: false,
flag4: false,
flag5: false,
reserved_zero_two_bits: 0,
},
level_idc: 40,
seq_parameter_set_id: ParamSetId(
0,
),
chroma_info: ChromaInfo {
chroma_format: YUV420,
separate_colour_plane_flag: false,
bit_depth_luma_minus8: 0,
bit_depth_chroma_minus8: 0,
qpprime_y_zero_transform_bypass_flag: false,
scaling_matrix: SeqScalingMatrix,
},
log2_max_frame_num_minus4: 12,
pic_order_cnt: TypeTwo,
max_num_ref_frames: 1,
gaps_in_frame_num_value_allowed_flag: false,
pic_width_in_mbs_minus1: 39,
pic_height_in_map_units_minus1: 29,
frame_mbs_flags: Frames,
direct_8x8_inference_flag: true,
frame_cropping: None,
vui_parameters: Some(
VuiParameters {
aspect_ratio_info: None,
overscan_appropriate: Unspecified,
video_signal_type: None,
chroma_loc_info: None,
timing_info: Some(
TimingInfo {
num_units_in_tick: 1,
time_scale: 40,
fixed_frame_rate_flag: false,
},
),
nal_hrd_parameters: None,
vcl_hrd_parameters: None,
low_delay_hrd_flag: None,
pic_struct_present_flag: false,
bitstream_restrictions: Some(
BitstreamRestrictions {
motion_vectors_over_pic_boundaries_flag: true,
max_bytes_per_pic_denom: 0,
max_bits_per_mb_denom: 0,
log2_max_mv_length_horizontal: 9,
log2_max_mv_length_vertical: 7,
max_num_reorder_frames: 0,
max_dec_frame_buffering: 1,
},
),
},
),
}
*/
} bluenvironpackage main
import (
"fmt"
"log"
"github.com/bluenviron/mediacommon/pkg/codecs/h264"
)
func main() {
var sps h264.SPS
err := sps.Unmarshal([]byte{39, 77, 224, 40, 141, 104, 10, 3, 218, 16, 0, 0, 3, 0, 16, 0, 0, 3, 2, 128, 241, 66, 42})
if err != nil {
log.Fatalf("sps wouldn't parse: %v", err)
}
fmt.Printf("sps: %+v\n", sps)
fmt.Printf("vui: %+v\n", sps.VUI)
/*
sps: {
ProfileIdc:77
ConstraintSet0Flag:true
ConstraintSet1Flag:true
ConstraintSet2Flag:true
ConstraintSet3Flag:false
ConstraintSet4Flag:false
ConstraintSet5Flag:false
LevelIdc:40
ID:0
ChromaFormatIdc:1
SeparateColourPlaneFlag:false
BitDepthLumaMinus8:0
BitDepthChromaMinus8:0
QpprimeYZeroTransformBypassFlag:false
ScalingList4x4:[]
UseDefaultScalingMatrix4x4Flag:[]
ScalingList8x8:[]
UseDefaultScalingMatrix8x8Flag:[]
Log2MaxFrameNumMinus4:12
PicOrderCntType:2
Log2MaxPicOrderCntLsbMinus4:0
DeltaPicOrderAlwaysZeroFlag:false
OffsetForNonRefPic:0
OffsetForTopToBottomField:0
OffsetForRefFrames:[]
MaxNumRefFrames:1
GapsInFrameNumValueAllowedFlag:false
PicWidthInMbsMinus1:39
PicHeightInMapUnitsMinus1:29
FrameMbsOnlyFlag:true
MbAdaptiveFrameFieldFlag:false
Direct8x8InferenceFlag:true
FrameCropping:<nil>
VUI: &{
AspectRatioInfoPresentFlag:false
AspectRatioIdc:0
SarWidth:0
SarHeight:0
OverscanInfoPresentFlag:false
OverscanAppropriateFlag:false
VideoSignalTypePresentFlag:false
VideoFormat:0
VideoFullRangeFlag:false
ColourDescriptionPresentFlag:false
ColourPrimaries:0
TransferCharacteristics:0
MatrixCoefficients:0
ChromaLocInfoPresentFlag:false
ChromaSampleLocTypeTopField:0
ChromaSampleLocTypeBottomField:0
TimingInfo:0xc000012220
NalHRD:<nil>
VclHRD:<nil>
LowDelayHrdFlag:false
PicStructPresentFlag:false
BitstreamRestriction:0xc00001c200
}
}
*/
} vdkpackage main
import (
"fmt"
"log"
"github.com/deepch/vdk/codec/h264parser"
)
func main() {
sps, err := h264parser.ParseSPS([]byte{39, 77, 224, 40, 141, 104, 10, 3, 218, 16, 0, 0, 3, 0, 16, 0, 0, 3, 2, 128, 241, 66, 42})
if err != nil {
log.Fatalf("sps wouldn't parse: %v", err)
}
fmt.Printf("sps: %+v\n", sps)
/*
sps: {
Id:0 ProfileIdc:77
LevelIdc:40
ConstraintSetFlag:56
MbWidth:40
MbHeight:30
CropLeft:0
CropRight:0
CropTop:0
CropBottom:0
Width:640
Height:480
FPS:20
}
*/
} |
Servers are not supposed to use Annex B sequences in RTP payloads, but V380 cameras do. Retina promises that it "works around brokenness in cheap closed-source cameras", so let's try to make this work. As noted by @Curid in #108, there's prior art: gortsp does Annex B decoding. ffmpeg also appears to support this, perhaps by accident: the output from its RTP layer is in Annex B format, and it doesn't error on Annex B sequences in RTP, so callers implicitly get the same result with proper or improper framing. Along the way, notice NALs that illegally contain the sequences `00 00 00` or `00 00 02` and ones that illegally end with `00`. We'll see if this happens in practice, but I'd prefer to explicitly consider how to work around it if so, rather than passing along bad data unknowingly. Throughput on my laptop falls from 3.4 GiB/s to 2.9 GiB/s on the `depacketize/h264_aac_discard` test, which uses realistic data. I think that's acceptable. The code avoids unnecessary copies (or refcounts even) and uses `memchr::memchr` to optimize the case of looking for the next zero byte. From skimming a profile, most of the added time is in `memchr`, so I don't think we're going to do much better than that. Fixes #68 Fixes #108
Can you give this a spin with the |
User reports the following error with this commit:
The latest commit outputs a working mp4 file. |
wireshark_dumps.zip
The text was updated successfully, but these errors were encountered: