Skip to content
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

mkvalidator: fix Vorbis 0 SamplingFrequency #201

Merged
merged 12 commits into from
Jan 2, 2025
Merged
2 changes: 0 additions & 2 deletions corec/corec/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@

#define STORE32LE(p, i) STORE8(p, 0, i), STORE8(p, 1, ((uint32_t)i) >> 8), STORE8(p, 2, ((uint32_t)i) >> 16), STORE8(p, 3, ((uint32_t)i) >> 24)

#define _abs(a) (((a)>=0)?(a):-(a))

static INLINE int64_t Scale64(int64_t v,int64_t Num,int64_t Den)
{
if (Den)
Expand Down
5 changes: 3 additions & 2 deletions corec/corec/helpers/parser/parser2.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*
****************************************************************************/

#include <stdlib.h>
#include "parser.h"
#include "strtypes.h"
#include "strtab.h"
Expand Down Expand Up @@ -977,8 +978,8 @@ void SimplifyFrac(cc_fraction* f, int64_t Num, int64_t Den)
{
bool_t Sign = (Num<0) != (Den<0);

Num = _abs(Num);
Den = _abs(Den);
Num = llabs(Num);
Den = llabs(Den);

if (Num>INT_MAX || Den>INT_MAX)
{
Expand Down
3 changes: 2 additions & 1 deletion corec/corec/helpers/parser/strtypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*
****************************************************************************/

#include <stdlib.h>
#include "strtypes.h"
#include "parser.h"
#include <corec/helpers/date/date.h>
Expand Down Expand Up @@ -47,7 +48,7 @@ void FractionToString(tchar_t* Out, size_t OutLen, const cc_fraction* p, int Per

if (Percent)
{
while (_abs(Num) > INT_MAX/100)
while (labs(Num) > INT_MAX/100)
{
Num >>= 1;
Den >>= 1;
Expand Down
6 changes: 3 additions & 3 deletions libmatroska2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ project("matroska2" VERSION 0.22.3 LANGUAGES C)
option(CONFIG_ZLIB "Enable zlib (de)compression" ON)
option(CONFIG_BZLIB "Enable bzlib decompression in libmatroska2" ON)
option(CONFIG_LZO1X "Enable lzo decompression in libmatroska2" ON)
option(CONFIG_NOCODEC_HELPER "Enable Vorbis frame durations in libmatroska2" ON)
option(CONFIG_CODEC_HELPER "Enable Vorbis frame durations in libmatroska2" ON)

if (CONFIG_ZLIB)
include(FindZLIB)
Expand Down Expand Up @@ -75,10 +75,10 @@ if (CONFIG_BZLIB)
endif()
endif(CONFIG_BZLIB)

if (NOT CONFIG_NOCODEC_HELPER)
if (CONFIG_CODEC_HELPER)
add_subdirectory("tremor")
target_link_libraries("matroska2" PRIVATE $<BUILD_INTERFACE:tremor>)
endif(NOT CONFIG_NOCODEC_HELPER)
endif(CONFIG_CODEC_HELPER)

set_target_properties("matroska2" PROPERTIES
PUBLIC_HEADER "${matroska2_PUBLIC_HEADERS}"
Expand Down
2 changes: 1 addition & 1 deletion libmatroska2/matroska_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#cmakedefine CONFIG_ZLIB
#cmakedefine CONFIG_LZO1X
#cmakedefine CONFIG_BZLIB
#cmakedefine CONFIG_NOCODEC_HELPER
#cmakedefine CONFIG_CODEC_HELPER

#define LIBMATROSKA2_PROJECT_VERSION T("@matroska2_VERSION_MAJOR@.@matroska2_VERSION_MINOR@.@matroska2_VERSION_PATCH@")
#define LIBMATROSKA2_VERSION ((@matroska2_VERSION_MAJOR@ << 24) | (@matroska2_VERSION_MINOR@ << 16) | @matroska2_VERSION_PATCH@)
5 changes: 2 additions & 3 deletions libmatroska2/matroskablock.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
#include "matroska2/matroska.h"
#include "matroska2/matroska_sem.h"
#include "matroska2/matroska_classes.h"
#if !defined(CONFIG_NOCODEC_HELPER)
#if defined(CONFIG_CODEC_HELPER)
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "misc.h"
#endif

#include <corec/str/str.h>
Expand Down Expand Up @@ -195,7 +194,7 @@ err_t MATROSKA_BlockProcessFrameDurations(matroska_block *Block, struct stream *
}
}
}
#if !defined(CONFIG_NOCODEC_HELPER)
#if defined(CONFIG_CODEC_HELPER)
else if (tcsisame_ascii(CodecID,T("A_VORBIS")))
{
Block->IsKeyframe = 1; // safety
Expand Down
10 changes: 0 additions & 10 deletions libmatroska2/tremor/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,6 @@
#include "registry.h"
#include "misc.h"

static int ilog(unsigned int v){
int ret=0;
if(v)--v;
while(v){
ret++;
v>>=1;
}
return(ret);
}

/* pcm accumulator examples (not exhaustive):

<-------------- lW ---------------->
Expand Down
12 changes: 0 additions & 12 deletions libmatroska2/tremor/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,6 @@ void vorbis_comment_init(vorbis_comment *vc){
memset(vc,0,sizeof(*vc));
}

/* This is more or less the same as strncasecmp - but that doesn't exist
* everywhere, and this is a fairly trivial function, so we include it */
static int tagcompare(const char *s1, const char *s2, int n){
int c=0;
while(c < n){
if(toupper(s1[c]) != toupper(s2[c]))
return !0;
c++;
}
return 0;
}

void vorbis_comment_clear(vorbis_comment *vc){
if(vc){
long i;
Expand Down
10 changes: 1 addition & 9 deletions libmatroska2/tremor/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

#ifdef _WIN32
# include <malloc.h>
# define rint(x) (floor((x)+0.5f))
# define rint(x) (floor((x)+0.5f))
# define NO_FLOAT_MATH_LIB
# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
# define LITTLE_ENDIAN 1
Expand All @@ -53,12 +53,4 @@
# include <memory.h>
#endif

#ifndef min
# define min(x,y) ((x)>(y)?(y):(x))
#endif

#ifndef max
# define max(x,y) ((x)<(y)?(y):(x))
#endif

#endif /* _OS_H */
4 changes: 2 additions & 2 deletions libmatroska2/tremor/sharedbook.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
int index= (j/indexdiv)%quantvals;
int point=0;
int val=VFLOAT_MULTI(delta,delpoint,
abs(b->quantlist[index]),&point);
labs(b->quantlist[index]),&point);

val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
val=VFLOAT_ADD(last,lastpoint,val,point,&point);
Expand Down Expand Up @@ -246,7 +246,7 @@ ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
for(k=0;k<b->dim;k++){
int point=0;
int val=VFLOAT_MULTI(delta,delpoint,
abs(b->quantlist[j*b->dim+k]),&point);
labs(b->quantlist[j*b->dim+k]),&point);

val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
val=VFLOAT_ADD(last,lastpoint,val,point,&point);
Expand Down
4 changes: 4 additions & 0 deletions mkclean/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ target_include_directories("mkclean" PRIVATE ${CMAKE_CURRENT_BINARY_DIR})

target_link_libraries("mkclean" PUBLIC "matroska2" "ebml2" "corec")

if (CONFIG_CODEC_HELPER)
target_link_libraries("mkclean" PRIVATE $<BUILD_INTERFACE:tremor>)
endif(CONFIG_CODEC_HELPER)

# Source packaging script
configure_file(pkg.sh.in pkg.sh)
configure_file(src.br.in src.br)
Expand Down
104 changes: 102 additions & 2 deletions mkclean/mkclean.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <corec/str/str.h>
#include <corec/helpers/parser/parser.h>

#if defined(CONFIG_CODEC_HELPER)
#include "ivorbiscodec.h"
#endif

#ifndef CONFIG_EBML_WRITING
#error libebml2 was not built with writing support!
#endif
Expand Down Expand Up @@ -887,6 +891,87 @@ static bool_t HasTrackUID(ebml_master *Tracks, int TrackUID, const ebml_context
return 0;
}

static double GuessSamplingFreq(ebml_master *Track)
{
double SampleRate = 0x0p+0;
#if defined(CONFIG_CODEC_HELPER)
tchar_t CodecID[MAXPATH];
ebml_element *Elt = EBML_MasterGetChild(Track,MATROSKA_getContextCodecID(),DstProfile);
EBML_StringGet((ebml_string*)Elt,CodecID,TSIZEOF(CodecID));
if (tcsisame_ascii(CodecID,T("A_VORBIS")))
{
ebml_binary *CodecPrivate = (ebml_binary*) EBML_MasterFindChild(Track,MATROSKA_getContextCodecPrivate());
if (CodecPrivate != NULL)
{
vorbis_info vi;
vorbis_comment vc;
ogg_packet OggPacket;
ogg_reference OggRef;
ogg_buffer OggBuffer;
int n,i,j;

vorbis_info_init(&vi);
vorbis_comment_init(&vc);
memset(&OggPacket,0,sizeof(ogg_packet));

OggBuffer.data = (uint8_t*)EBML_BinaryGetData(CodecPrivate);
OggBuffer.size = (long)EBML_ElementDataSize((ebml_element*)CodecPrivate, 1);
OggBuffer.refcount = 1;

memset(&OggRef,0,sizeof(OggRef));
OggRef.buffer = &OggBuffer;
OggRef.next = NULL;

OggPacket.packet = &OggRef;
OggPacket.packetno = -1;

n = OggBuffer.data[0];
i = 1+n;
j = 1;

while (OggPacket.packetno < 3 && n>=j)
{
OggRef.begin = i;
OggRef.length = 0;
do
{
OggRef.length += OggBuffer.data[j];
}
while (OggBuffer.data[j++] == 255 && n>=j);
i += OggRef.length;

if (i > OggBuffer.size)
return ERR_INVALID_DATA;

++OggPacket.packetno;
OggPacket.b_o_s = OggPacket.packetno == 0;
OggPacket.bytes = OggPacket.packet->length;
if (!(vorbis_synthesis_headerin(&vi,&vc,&OggPacket) >= 0) && OggPacket.packetno==0)
return ERR_INVALID_DATA;
}

if (OggPacket.packetno < 3)
{
OggRef.begin = i;
OggRef.length = OggBuffer.size - i;

++OggPacket.packetno;
OggPacket.b_o_s = OggPacket.packetno == 0;
OggPacket.bytes = OggPacket.packet->length;

if (!(vorbis_synthesis_headerin(&vi,&vc,&OggPacket) >= 0) && OggPacket.packetno==0)
return ERR_INVALID_DATA;
}

SampleRate = vi.rate;
vorbis_comment_clear(&vc);
vorbis_info_clear(&vi);
}
}
#endif
return SampleRate;
}

static int CleanTracks(ebml_master *Tracks, int srcProfile, int *dstProfile, ebml_master *Attachments, array *Alternate3DTracks)
{
ebml_master *Track, *CurTrack, *OtherTrack;
Expand Down Expand Up @@ -1224,11 +1309,26 @@ static int CleanTracks(ebml_master *Tracks, int srcProfile, int *dstProfile, ebm
Elt = EBML_MasterFindChild(CurTrack,MATROSKA_getContextAudio());
if (Elt)
{
DisplayH = EBML_MasterGetChild((ebml_master*)Elt,MATROSKA_getContextSamplingFrequency(), DstProfile);
if (EBML_FloatValue((ebml_float*)DisplayH) == 0x0p+0)
{
double SamplingFreq = GuessSamplingFreq(CurTrack);
if (SamplingFreq != 0x0p+0)
{
if (!Quiet)
TextPrintf(StdErr,T("Invalid 0 SamplingFrequency value codec '%s' for profile '%s' in track %d, detected %f\r\n"),CodecID,GetProfileName(*dstProfile),TrackNum,SamplingFreq);
EBML_FloatSetValue((ebml_float*)DisplayH, SamplingFreq);
}
else
{
if (!Quiet)
TextPrintf(StdErr,T("Invalid 0 SamplingFrequency value codec '%s' for profile '%s' in track %d, using the default value\r\n"),CodecID,GetProfileName(*dstProfile),TrackNum);
NodeDelete((node*)CurTrack);
}
}
Elt2 = EBML_MasterFindChild((ebml_master*)Elt,MATROSKA_getContextOutputSamplingFrequency());
if (Elt2)
{
DisplayH = EBML_MasterFindChild((ebml_master*)Elt,MATROSKA_getContextSamplingFrequency());
assert(DisplayH!=NULL);
if (EBML_FloatValue((ebml_float*)Elt2) == EBML_FloatValue((ebml_float*)DisplayH))
NodeDelete((node*)Elt2);
}
Expand Down
3 changes: 2 additions & 1 deletion mkclean/regression/mkcleanreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def testFile(cli, line_num, src_file, mkclean_options, filesize, hash):
mkvalidator_exe = "mkvalidator"
mkvalidator_run = [mkvalidator_exe]
if cli.quiet:
mkvalidator_run.append("--no-warn")
mkvalidator_run.append("--quiet")
if '--live' in mkclean_options:
mkvalidator_run.append("--live")
Expand All @@ -74,7 +75,7 @@ def testFile(cli, line_num, src_file, mkclean_options, filesize, hash):
result = subprocess.run(mkvalidator_run)

if not result.returncode == 0:
print(f"Fail:6:{line_num}: mkvalidator returned {result} for {outputfile} in {src_file} for {mkclean_options}", file=sys.stderr)
print(f"Fail:6:{line_num}: mkvalidator returned 0x{result.returncode:03X} for {outputfile} in {src_file} for {mkclean_options}", file=sys.stderr)
return

filemd5 = hashlib.md5(open(outputfile,'rb').read()).hexdigest()
Expand Down
14 changes: 7 additions & 7 deletions mkclean/regression/regression.mkc
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,16 @@
"dts-bz2.mkv" "--remux --optimize" 59610381 98d24b3c6e92782b1f8da4f60ab14b45
"dts-bz2.mkv" "--unsafe" 59750039 1d8114732e1f9e0d9cb1fecc9f4dbc64
"dts-bz2.mkv" "--remux --unsafe" 59749650 f868eb64258a40ff3f4b142c25eccd8d
"chrome_linux_x64_fail.webm" "" 138037768 240d01b22ef925f27868efd48470ab63
"chrome_linux_x64_fail.webm" "--remux" 138037768 dcdb434ab0c953f5502b84799f09e012
"chrome_linux_x64_fail.webm" "--remux --optimize" 138037768 dcdb434ab0c953f5502b84799f09e012
"chrome_linux_x64_fail.webm" "--remux --unsafe" 138036732 fbe72bfdf6bfe463fe7cf67f25572ac2
"chrome_linux_x64_fail.webm" "" 138037768 40890ec7f3541c5148d35c205e9b3458
"chrome_linux_x64_fail.webm" "--remux" 138037768 82c7609bac30e124612a09da1c238873
"chrome_linux_x64_fail.webm" "--remux --optimize" 138037768 82c7609bac30e124612a09da1c238873
"chrome_linux_x64_fail.webm" "--remux --unsafe" 138036732 ca0f5b52200e70b1348e067cb9ad2dcd
"A_Digital_Media_Primer_For_Geeks-360p.webm" "" 138041303 560ef9192e79c610d040d7f2b82d0950
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--remux" 138037140 f8b9a51620b53789cfe2ec69c7cb488f
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--remux" 138037655 a3c59c22899bbcf98120e8eb59fe6106
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--optimize" 138041303 560ef9192e79c610d040d7f2b82d0950
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--remux --optimize" 138037140 f8b9a51620b53789cfe2ec69c7cb488f
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--remux --optimize" 138037655 a3c59c22899bbcf98120e8eb59fe6106
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--unsafe" 138039084 63c1c373b73312b0bee1d5847957c48b
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--remux --unsafe" 138036104 f00a30e724e67fbcef192668175dfb54
"A_Digital_Media_Primer_For_Geeks-360p.webm" "--remux --unsafe" 138036619 5289dc5076aa59f010c8b982dad7c478
"fake-side-by-side.webm" "" 138037777 9640e786a92f2ede26b6f45ad70fae62
"fake-side-by-side.webm" "--remux" 138037777 7f13e2640c0f2c0b885e38c9b5313c78
"fake-side-by-side.webm" "--optimize" 138037777 9640e786a92f2ede26b6f45ad70fae62
Expand Down
2 changes: 1 addition & 1 deletion mkvalidator/mkvalidator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ int main(int argc, const char *argv[])

if (!Quiet) TextWrite(StdErr,T("."));
if (RTrackInfo)
CheckTracks(RTrackInfo, MatroskaProfile);
Result |= CheckTracks(RTrackInfo, MatroskaProfile);

for (TI=ARRAYBEGIN(Tracks,track_info); TI!=ARRAYEND(Tracks,track_info); ++TI)
{
Expand Down
Loading