I am working on an mp3 decoder, the formula to determine the length, in bytes, of an mp3 frame is
FrameSize = 144 * BitRate / (SampleRate + Padding)
I can't find anywhere that explains what the '144' represents.
Does anyone know?
The 144 represents total bytes-per-frame.
MP3 files are generally encoded as MPEG-1 Layer 3.
There are 1152 samples per frame in type Layer 3.
1152 samples / 8 bits-per-byte = 144 bytes total.
Taking the formula for frame size (in bytes):
FrameSize = 144 * BitRate / (SampleRate + Padding)
We can see (for MP3 with 192 bitrate # 44.1 khz):
144 * 192 / (44.1 + 0) = 626 bytes per audio frame (fraction parts are ignored).
Related
I implemented a network video player (like VLC) using ffmpeg. But it can not decode AAC audio stream received from a IP camera. It can decode other audio sterams like G711, G726 etc. I set the codec ID as AV_CODEC_ID_AAC and I set channels and sample rate of AvCodecContext. But avcodec_decode_audio4 fails with an error code of INVALID_DATA. I checked previously asked questions, I tried to add extrabytes to AvCodecContext using media format specific parameters of "config=1408". And I set extradatabytes as 2 bytes of "20" and "8" but it also not worked. I appreciate any help, thanks.
IP CAMERA SDP:
a=rtpmap:96 mpeg4-generic/16000/1
a=fmtp:96 streamtype=5; profile-level-id=5; mode=AAC-hbr; config=1408; SizeLength=13; IndexLength=3; IndexDeltaLength=3
AVCodec* decoder = avcodec_find_decoder((::AVCodecID)id);//set as AV_CODEC_ID_AAC
AVCodecContext* decoderContext = avcodec_alloc_context3(decoder);
char* test = (char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi("1408").ToPointer();
unsigned int length;
uint8_t* extradata = parseGeneralConfigStr(test, length);//it is set as 0x14 and 0x08
decoderContext->channels = number_of_channels; //set as 1
decoderContext->sample_rate = sample_rate; //set as 16000
decoderContext->channel_layout = AV_CH_LAYOUT_MONO;
decoderContext->codec_type = AVMEDIA_TYPE_AUDIO;
decoderContext->extradata = (uint8_t*)av_malloc(AV_INPUT_BUFFER_PADDING_SIZE + length);
memcpy(decoderContext->extradata, extradata, length);
memset(decoderContext->extradata+ length, 0, AV_INPUT_BUFFER_PADDING_SIZE);
Did you check data for INVALID_DATA?
You can check it according to RFC
RFC3640 (3.2 RTP Payload Structure)
AAC Payload can be seperated like below
AU-Header | Size Info | ADTS | Data
Example payload 00 10 0c 00 ff f1 60 40 30 01 7c 01 30 35 ac
According to configs that u shared
AU-size (SizeLength=13)
AU-Index / AU-Index-delta (IndexLength=3/IndexDeltaLength=3)
The length in bits of AU-Header is 13(SizeLength) + 3(IndexLength/IndexDeltaLength) = 16.
AU-Header 00 10
You should use AU-size(SizeLength) value for Size Info
AU-size: Indicates the size in octets of the associated Access Unit in the Access Unit Data Section in the same RTP packet.
First 13 (SizeLength) bits 0000000000010 equals to 2. So read 2 octets for size info.
Size Info 0c 00
ADTS ff f1 60 40 30 01 7c
ADTS Parser
ID MPEG-4
MPEG Layer 0
CRC checksum absent 1
Profile Low Complexity profile (AAC LC)
Sampling frequency 16000
Private bit 0
Channel configuration 1
Original/copy 0
Home 0
Copyright identification bit 0
Copyright identification start 0
AAC frame length 384
ADTS buffer fullness 95
No raw data blocks in frame 0
Data starts with 01 30 35 ac.
I have a std::string that is base32 encoded and I have a function that decodes it. The function takes a char* input, a char* destination and a length. How do I know what length I will need for the destination? I need to know what array to allocate for the destination. How do I determine the size?
Base32 allows to encode each 5 bits ( as 32 = 2^5 ) using single character.
It means that you need output buffer size for encoding:
dst_size = src_size * 8 / 5 (1.6 times larger)
But as base32 string length must be multiple of 40 bits:
dst_size = (src_size * 8 + 4) / 5
Thus, for decoding (base32->binary) required buffer size is accordingly
dst_size = ceil( src_size / 1.6 )
Actually, the encoded base32 string length is computed as follow :
ceil(bytesLength / 5.d) * 8
bytesLength / 5.f because we want to know how many chunks of 5 bytes we have, and ceil because 0.1 chunk is still 1 chunk
ceil(bytesLength / 5.f) * 8 because a chunk is made of 8 characters.
For the input data 'a' the encoded result will be ME====== because we have 1 chunk of 8 characters : two 5bits encoded characters (ME) 6 padding characters (======)
The same fashion, the decoded length is :
bytesLength * 5 / 8
But here bytesLength is not including the padding characters, thuse for ME====== bytelength is 2, giving 2 * 5 / 8 == 1 we only have 1 byte to decode.
For a visual explanation, see rfc4648 section 9 (page 11)
I've got an issue with a program that should send me back the free disk space usable by any user.
My goal is to get all the free disk space of every partitions of my hard drive that is usable by anyone who doesn't have sudo rights.
So I tryed this :
int main() {
struct statvfs diskData;
statvfs("/", &diskData);
unsigned long long available = (diskData.f_favail + diskData.f_bavail) * diskData.f_frsize) / (1024 * 1024)
std::cout << "Free Space : " << available << std::endl;
}
This gives me a total of 2810 ...
However, when I output df -h, I can read that the available space is 25G for sda3 and 30G for sda1
This seems completely inaccurate.
I've been running on the posts on Stackoverflow, mixing solutions I saw, but none is satisfactory. How can I get a correct value in Megabytes of my available free space ?
EDIT : Full statvfs and df / output
statvfs :
Block Size : 4 096
Fragment Size : 4 096
Blocks : 9 612 197
Free Blocks : 7 009 166
Non Root Free Blocks : 6 520 885
Inodes : 2 444 624
Free Inodes Space : 2 137 054
Non Root Free Inodes : 2 137 054
File System ID : 4 224 884 198
Mount Flags : 4 096
Max Filename Length : 255
df / :
Filesystem 1K-Blocks Used Available Use% Mounted on
/dev/sda3 38 448 788 10 412 112 26 083 556 29% /
This seems like a more accurate measure of the free disk space:
unsigned long long available = (diskData.f_bavail * diskData.f_bsize) / (1024 * 1024);
It matches the output from df quite closely on my system (df shows the sizes in gigs, and probably rounds them).
If you want the output in gigs like df you could use this:
#include <sys/statvfs.h>
#include <stdio.h>
unsigned long rounddiv(unsigned long num, unsigned long divisor) {
return (num + (divisor/2)) / divisor;
}
int main() {
struct statvfs diskData;
statvfs("/home", &diskData);
unsigned long available = diskData.f_bavail * diskData.f_bsize;
printf("Free Space : %luG\n", rounddiv(available, 1024*1024*1024));
return 0;
}
The output from this on my system:
Free Space : 31G
And if I run df -h /home:
Filesystem Size Used Avail Use% Mounted on
181G 141G 31G 83% /home
It seems that the right value to use is the fragment size, not the block size (i.e. f_frsize)
Have you tried with
diskData.f_bavail * diskData.f_frsize
instead ?
Why did they do this:
Sys_SetPhysicalWorkMemory( 192 << 20, 1024 << 20 ); //Min = 201,326,592 Max = 1,073,741,824
Instead of this:
Sys_SetPhysicalWorkMemory( 201326592, 1073741824 );
The article I got the code from
A neat property is that shifting a value << 10 is the same as multiplying it by 1024 (1 KiB), and << 20 is 1024*1024, (1 MiB).
Shifting by successive powers of 10 yields all of our standard units of computer storage:
1 << 10 = 1 KiB (Kibibyte)
1 << 20 = 1 MiB (Mebibyte)
1 << 30 = 1 GiB (Gibibyte)
...
So that function is expressing its arguments to Sys_SetPhysicalWorkMemory(int minBytes, int maxBytes) as 192 MB (min) and 1024 MB (max).
Self commenting code:
192 << 20 means 192 * 2^20 = 192 * 2^10 * 2^10 = 192 * 1024 * 1024 = 192 MByte
1024 << 20 means 1024 * 2^20 = 1 GByte
Computations on constants are optimized away so nothing is lost.
I might be wrong (and I didn't study the source) , but I guess it's just for readability reasons.
I think the point (not mentioned yet) is that
All but the most basic compilers will do the shift at compilation time. Whenever you use operators with constant expressions, the
compiler will be able to do this before the code is even generated.
Note, that before constexpr and C++11, this did not extend to
functions.
At the begin sorry for my English.
My purpose is to load rgb array from the bitmap. But there is a difference between size of the image and the product of height * width * 3. When i read about bmp format i notice when the widht % 4 is != 0 then i must add to width some digit to equilibrium. (width%4==1 i must add 3, width%4==2 i must add 2 etc.)
Size of the image is 1 442 454 Bytes, height is 601 and width is 801.
804 * 600 * 3 == 1 441 800 and it is more then size of the image.
801 * 600 * 3 == 1441800 it must less then size of the image (even when I add 54 bits of headers). What i must do to read it correctly? (headers are loaded correctly)
Note that each row is padded to a multiple of 4 bytes (not pixels).
So if you have 801 pixels per row and each pixel is 3 bytes (RGB) them you have 801*3=2403 bytes per row and this will be padded with one additional byte to 2404 bytes. The bitmap size will therefore be 601*2404=1444804 bytes.
If however your row width is only 800 pixels then you have 800*3=2440 bytes per row which is already a multiple of 4 bytes so there will be no additional pad bytes and the bitmap size will be 601*2400=1442400 bytes. With a 54 byte header this gives 1442454 bytes.
Conclusion: your image size is actually 801 x 600, not 801 x 601.