Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Opus
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Xiph.Org
Opus
Commits
885d7038
Verified
Commit
885d7038
authored
2 years ago
by
Jean-Marc Valin
Browse files
Options
Downloads
Patches
Plain Diff
Make FEC handling in opus_demo more general
Now only running the decoder on "received" packets
parent
d1b48b71
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/opus_demo.c
+56
-55
56 additions, 55 deletions
src/opus_demo.c
with
56 additions
and
55 deletions
src/opus_demo.c
+
56
−
55
View file @
885d7038
...
...
@@ -216,10 +216,10 @@ int main(int argc, char *argv[])
OpusEncoder
*
enc
=
NULL
;
OpusDecoder
*
dec
=
NULL
;
int
args
;
int
len
[
2
]
;
int
len
;
int
frame_size
,
channels
;
opus_int32
bitrate_bps
=
0
;
unsigned
char
*
data
[
2
]
=
{
NULL
,
NULL
}
;
unsigned
char
*
data
=
NULL
;
unsigned
char
*
fbytes
=
NULL
;
opus_int32
sampling_rate
;
int
use_vbr
;
...
...
@@ -243,8 +243,7 @@ int main(int argc, char *argv[])
int
bandwidth
=
OPUS_AUTO
;
const
char
*
bandwidth_string
;
int
lost
=
0
,
lost_prev
=
1
;
int
toggle
=
0
;
opus_uint32
enc_final_range
[
2
];
opus_uint32
enc_final_range
;
opus_uint32
dec_final_range
;
int
encode_only
=
0
,
decode_only
=
0
;
int
max_frame_size
=
48000
*
2
;
...
...
@@ -264,6 +263,7 @@ int main(int argc, char *argv[])
int
variable_duration
=
OPUS_FRAMESIZE_ARG
;
int
delayed_decision
=
0
;
int
ret
=
EXIT_FAILURE
;
int
lost_count
=
0
;
if
(
argc
<
5
)
{
...
...
@@ -587,10 +587,7 @@ int main(int argc, char *argv[])
out
=
(
short
*
)
malloc
(
max_frame_size
*
channels
*
sizeof
(
short
));
/* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */
fbytes
=
(
unsigned
char
*
)
malloc
(
max_frame_size
*
channels
*
sizeof
(
short
));
data
[
0
]
=
(
unsigned
char
*
)
calloc
(
max_payload_bytes
,
sizeof
(
unsigned
char
));
if
(
use_inbandfec
)
{
data
[
1
]
=
(
unsigned
char
*
)
calloc
(
max_payload_bytes
,
sizeof
(
unsigned
char
));
}
data
=
(
unsigned
char
*
)
calloc
(
max_payload_bytes
,
sizeof
(
unsigned
char
));
if
(
delayed_decision
)
{
if
(
frame_size
==
sampling_rate
/
400
)
...
...
@@ -652,22 +649,22 @@ int main(int argc, char *argv[])
num_read
=
fread
(
ch
,
1
,
4
,
fin
);
if
(
num_read
!=
4
)
break
;
len
[
toggle
]
=
char_to_int
(
ch
);
if
(
len
[
toggle
]
>
max_payload_bytes
||
len
[
toggle
]
<
0
)
len
=
char_to_int
(
ch
);
if
(
len
>
max_payload_bytes
||
len
<
0
)
{
fprintf
(
stderr
,
"Invalid payload length: %d
\n
"
,
len
[
toggle
]
);
fprintf
(
stderr
,
"Invalid payload length: %d
\n
"
,
len
);
break
;
}
num_read
=
fread
(
ch
,
1
,
4
,
fin
);
if
(
num_read
!=
4
)
break
;
enc_final_range
[
toggle
]
=
char_to_int
(
ch
);
num_read
=
fread
(
data
[
toggle
],
1
,
len
[
toggle
]
,
fin
);
if
(
num_read
!=
(
size_t
)
len
[
toggle
]
)
enc_final_range
=
char_to_int
(
ch
);
num_read
=
fread
(
data
,
1
,
len
,
fin
);
if
(
num_read
!=
(
size_t
)
len
)
{
fprintf
(
stderr
,
"Ran out of input, "
"expecting %d bytes got %d
\n
"
,
len
[
toggle
]
,(
int
)
num_read
);
len
,(
int
)
num_read
);
break
;
}
}
else
{
...
...
@@ -696,8 +693,8 @@ int main(int argc, char *argv[])
if
(
encode_only
||
decode_only
)
stop
=
1
;
}
len
[
toggle
]
=
opus_encode
(
enc
,
in
,
frame_size
,
data
[
toggle
]
,
max_payload_bytes
);
nb_encoded
=
opus_packet_get_samples_per_frame
(
data
[
toggle
]
,
sampling_rate
)
*
opus_packet_get_nb_frames
(
data
[
toggle
],
len
[
toggle
]
);
len
=
opus_encode
(
enc
,
in
,
frame_size
,
data
,
max_payload_bytes
);
nb_encoded
=
opus_packet_get_samples_per_frame
(
data
,
sampling_rate
)
*
opus_packet_get_nb_frames
(
data
,
len
);
remaining
=
frame_size
-
nb_encoded
;
for
(
i
=
0
;
i
<
remaining
*
channels
;
i
++
)
in
[
i
]
=
in
[
nb_encoded
*
channels
+
i
];
...
...
@@ -716,10 +713,10 @@ int main(int argc, char *argv[])
bitrate_bps
=
1000
;
opus_encoder_ctl
(
enc
,
OPUS_SET_BITRATE
(
bitrate_bps
));
}
opus_encoder_ctl
(
enc
,
OPUS_GET_FINAL_RANGE
(
&
enc_final_range
[
toggle
]
));
if
(
len
[
toggle
]
<
0
)
opus_encoder_ctl
(
enc
,
OPUS_GET_FINAL_RANGE
(
&
enc_final_range
));
if
(
len
<
0
)
{
fprintf
(
stderr
,
"opus_encode() returned %d
\n
"
,
len
[
toggle
]
);
fprintf
(
stderr
,
"opus_encode() returned %d
\n
"
,
len
);
goto
failure
;
}
curr_mode_count
+=
frame_size
;
...
...
@@ -731,56 +728,60 @@ int main(int argc, char *argv[])
}
#if 0 /* This is for testing the padding code, do not enable by default */
if (len
[toggle]
<1275)
if (len<1275)
{
int new_len = len
[toggle]
+rand()%(max_payload_bytes-len
[toggle]
);
if ((err = opus_packet_pad(data
[toggle], len[toggle]
, new_len)) != OPUS_OK)
int new_len = len+rand()%(max_payload_bytes-len);
if ((err = opus_packet_pad(data
, len
, new_len)) != OPUS_OK)
{
fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
goto failure;
}
len
[toggle]
= new_len;
len = new_len;
}
#endif
if
(
encode_only
)
{
unsigned
char
int_field
[
4
];
int_to_char
(
len
[
toggle
]
,
int_field
);
int_to_char
(
len
,
int_field
);
if
(
fwrite
(
int_field
,
1
,
4
,
fout
)
!=
4
)
{
fprintf
(
stderr
,
"Error writing.
\n
"
);
goto
failure
;
}
int_to_char
(
enc_final_range
[
toggle
]
,
int_field
);
int_to_char
(
enc_final_range
,
int_field
);
if
(
fwrite
(
int_field
,
1
,
4
,
fout
)
!=
4
)
{
fprintf
(
stderr
,
"Error writing.
\n
"
);
goto
failure
;
}
if
(
fwrite
(
data
[
toggle
],
1
,
len
[
toggle
]
,
fout
)
!=
(
unsigned
)
len
[
toggle
]
)
{
if
(
fwrite
(
data
,
1
,
len
,
fout
)
!=
(
unsigned
)
len
)
{
fprintf
(
stderr
,
"Error writing.
\n
"
);
goto
failure
;
}
tot_samples
+=
nb_encoded
;
}
else
{
opus_int32
output_samples
;
lost
=
len
[
toggle
]
==
0
||
(
packet_loss_perc
>
0
&&
rand
()
%
100
<
packet_loss_perc
);
int
fr
;
int
run_decoder
;
lost
=
len
==
0
||
(
packet_loss_perc
>
0
&&
rand
()
%
100
<
packet_loss_perc
);
if
(
lost
)
opus_decoder_ctl
(
dec
,
OPUS_GET_LAST_PACKET_DURATION
(
&
output_samples
));
else
output_samples
=
max_frame_size
;
if
(
count
>=
use_inbandfec
)
{
/* delay by one packet when using in-band FEC */
if
(
use_inbandfec
)
{
if
(
lost_prev
)
{
/* attempt to decode with in-band FEC from next packet */
opus_decoder_ctl
(
dec
,
OPUS_GET_LAST_PACKET_DURATION
(
&
output_samples
));
output_samples
=
opus_decode
(
dec
,
lost
?
NULL
:
data
[
toggle
],
len
[
toggle
],
out
,
output_samples
,
1
);
}
else
{
/* regular decode */
output_samples
=
max_frame_size
;
output_samples
=
opus_decode
(
dec
,
data
[
1
-
toggle
],
len
[
1
-
toggle
],
out
,
output_samples
,
0
);
}
{
lost_count
++
;
run_decoder
=
0
;
}
else
{
run_decoder
=
1
;
}
if
(
run_decoder
)
run_decoder
+=
lost_count
;
/* FIXME: Figure out how to trigger the decoder when the last packet of the file is lost. */
for
(
fr
=
0
;
fr
<
run_decoder
;
fr
++
)
{
opus_int32
output_samples
=
0
;
if
(
fr
<
lost_count
-
1
)
{
opus_decoder_ctl
(
dec
,
OPUS_GET_LAST_PACKET_DURATION
(
&
output_samples
));
output_samples
=
opus_decode
(
dec
,
NULL
,
0
,
out
,
output_samples
,
1
);
}
else
if
(
fr
==
lost_count
-
1
)
{
opus_decoder_ctl
(
dec
,
OPUS_GET_LAST_PACKET_DURATION
(
&
output_samples
));
output_samples
=
opus_decode
(
dec
,
data
,
len
,
out
,
output_samples
,
1
);
}
else
{
output_samples
=
opus_decode
(
dec
,
lost
?
NULL
:
data
[
toggle
],
len
[
toggle
],
out
,
output_samples
,
0
);
output_samples
=
max_frame_size
;
output_samples
=
opus_decode
(
dec
,
data
,
len
,
out
,
output_samples
,
0
);
}
if
(
output_samples
>
0
)
{
...
...
@@ -817,24 +818,26 @@ int main(int argc, char *argv[])
if
(
!
encode_only
)
opus_decoder_ctl
(
dec
,
OPUS_GET_FINAL_RANGE
(
&
dec_final_range
));
/* compare final range encoder rng values of encoder and decoder */
if
(
enc_final_range
[
toggle
^
use_inbandfec
]
!=
0
&&
!
encode_only
if
(
enc_final_range
!=
0
&&
!
encode_only
&&
!
lost
&&
!
lost_prev
&&
dec_final_range
!=
enc_final_range
[
toggle
^
use_inbandfec
]
)
{
&&
dec_final_range
!=
enc_final_range
)
{
fprintf
(
stderr
,
"Error: Range coder state mismatch "
"between encoder and decoder "
"in frame %ld: 0x%8lx vs 0x%8lx
\n
"
,
(
long
)
count
,
(
unsigned
long
)
enc_final_range
[
toggle
^
use_inbandfec
]
,
(
unsigned
long
)
enc_final_range
,
(
unsigned
long
)
dec_final_range
);
goto
failure
;
}
lost_prev
=
lost
;
if
(
!
lost
)
lost_count
=
0
;
if
(
count
>=
use_inbandfec
)
{
/* count bits */
bits
+=
len
[
toggle
]
*
8
;
bits_max
=
(
len
[
toggle
]
*
8
>
bits_max
)
?
len
[
toggle
]
*
8
:
bits_max
;
bits2
+=
len
[
toggle
]
*
len
[
toggle
]
*
64
;
bits
+=
len
*
8
;
bits_max
=
(
len
*
8
>
bits_max
)
?
len
*
8
:
bits_max
;
bits2
+=
len
*
len
*
64
;
if
(
!
decode_only
)
{
nrg
=
0
.
0
;
...
...
@@ -843,13 +846,12 @@ int main(int argc, char *argv[])
}
nrg
/=
frame_size
*
channels
;
if
(
nrg
>
1e5
)
{
bits_act
+=
len
[
toggle
]
*
8
;
bits_act
+=
len
*
8
;
count_act
++
;
}
}
}
count
++
;
toggle
=
(
toggle
+
use_inbandfec
)
&
1
;
}
if
(
decode_only
&&
count
>
0
)
...
...
@@ -879,8 +881,7 @@ int main(int argc, char *argv[])
failure:
opus_encoder_destroy
(
enc
);
opus_decoder_destroy
(
dec
);
free
(
data
[
0
]);
free
(
data
[
1
]);
free
(
data
);
if
(
fin
)
fclose
(
fin
);
if
(
fout
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment