Перевод текста на русский язык:
// Именно строка «BM», то есть все файлы с расширением .bmp имеют первые два байта «BM». // 'BM' обозначает, что это формат изображения Windows, поддерживаемый.
typedef struct {
unsigned int bfSize; // указывает размер файла в байтах, включая эти 14 байт.
unsigned short bfReserved1; // зарезервированное слово, не используется.
unsigned short bfReserved2; // зарезервированное слово, не используется.
unsigned int bfOffBits; // смещение от начала файла до данных в битах, в байтах.
}BITMAPFILEHEADER;
// Структура заголовка информации о растровом изображении
typedef struct {
unsigned int biSize; // размер этой структуры в байтах, обычно 40 байт.
unsigned int biWidth; // ширина изображения в пикселях.
unsigned int biHeight; // высота изображения в пикселях.
// Примечание: это значение имеет другое применение, кроме описания высоты изображения. Оно также указывает, является ли изображение обратным растровым изображением или прямым. Если значение положительное, изображение обратное, если отрицательное — прямое. Большинство файлов BMP являются обратными растровыми изображениями, то есть значение высоты положительное.
unsigned short biPlanes; // для целевой аппаратуры указывает количество цветовых плоскостей, должно быть равно 1, не используется.
unsigned short biBitCount; // глубина цвета, количество бит, необходимое для каждого пикселя.
unsigned int biCompression; // тип сжатия растрового изображения.
unsigned int biSizeImage; // размер растрового изображения в байтах.
unsigned int biXPelsPerMeter; // разрешение растрового изображения по горизонтали, пикселей на метр.
unsigned int biYPelsPerMeter; // разрешение растрового изображения по вертикали, пикселей на метр.
unsigned int biClrUsed; // количество используемых цветов в таблице цветов растрового изображения.
unsigned int biClrImportant; // количество важных цветов при отображении растрового изображения.
} BITMAPINFOHEADER;
BMP использует порядок хранения Little Endian. В этом порядке хранения «RGB24» компоненты пикселей хранятся в следующем порядке: B, G, R. Поскольку формат RGB24 хранит компоненты в порядке R, G, B, необходимо поменять местами «R» и «B» перед сохранением.
Обратите внимание: в среде Visual Studio структура по умолчанию выровнена по одному байту, то есть кратна 8. В среде GCC структура по умолчанию выровнена по четырем байтам, то есть кратна 32.
Эта программа реализует формулу преобразования RGB в YUV:
Способ вызова:
./rgb24_to_yuv420p ./mediadata/lena_256x256_rgb24.rgb 256 256
Внимание:
Программа rgb24_colorbar.cpp выводит девять цветов спектра: красный, оранжевый, жёлтый, зелёный, голубой, синий, фиолетовый, белый и чёрный.
Результат вывода выглядит следующим образом:
Исходный поток H.264 состоит из отдельных блоков NALU.
Каждый блок NALU отделяется стартовым кодом (startcode).
Существует два вида стартовых кодов: 0x000001 (3Byte) или 0x00000001 (4Byte).
Если NALU соответствует началу кадра, используется 0x00000001, иначе используется 0x000001.
Процесс анализа исходного потока H.264 включает следующие шаги:
Сначала в исходном потоке ищутся 0x000001 и 0x00000001 для разделения блоков NALU; Затем анализируются поля каждого блока NALU.
Структура заголовка NALU: тип NALU (5 бит), индикатор важности (2 бита), запрещающий бит (1 бит).
- Тип NALU: 1–12 используются в H.264, 24–31 используются приложениями, отличными от H.264.
- Индикатор важности: указывает на важность этого блока NAL при восстановлении, чем больше значение, тем важнее. (Nal_ref_idc: представляет приоритет NAL. 0–3, чем больше значение, тем более важным является текущий NAL, который должен быть защищён в первую очередь. Если текущий NAL является частью начального кадра, или последовательностью параметров, или набором графических параметров, эти важные единицы должны быть больше 0.)
- Запрещающий бит: когда сетевой приёмник обнаруживает ошибку бита в блоке NAL, этот бит устанавливается в 1, чтобы приёмник отбросил этот блок.
Примечание: частота дискретизации звука в этой статье составляет 44100 Гц, а формат выборки — 16 LE. «16» означает, что разрядность выборки составляет 16 бит. Поскольку 1 байт = 8 бит, один образец канала занимает 2 байта. «LE» означает Little Endian, представляя способ хранения двухбайтовых значений выборки с высоким адресом, содержащим старший байт.
//
//Эта программа может разделить данные PCM16LE на левый и правый каналы.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pcm16le_split(const char *file)
{
if (file == NULL) {
printf("Путь к файлу пуст!\n");
return 0;
}
FILE *fp = fopen(file, "rb+");
if (fp == NULL) {
printf("Ошибка открытия файла!\n");
return 0;
}
FILE *fp_l = fopen("./output/output_l.pcm", "wb+");
if (fp_l == NULL) {
printf("Не удалось открыть или создать файл левого канала!\n");
return 0;
}
FILE *fp_r = fopen("./output/output_r.pcm", "wb+");
if (fp_r == NULL) {
printf("Не удалось открыть или создать файл правого канала!\n");
return 0;
}
unsigned char buf[4] = {0};
//В данных PCM16LE значения выборки для левого и правого каналов разделены.
//Каждое значение выборки занимает 2 байта пространства.
while (!feof(fp)) {
fread(buf, 1, 4, fp);
//Сохраняем данные левого канала, одно значение выборки 16-битное, два байта
fwrite(buf, 1, 2, fp_l);
//Сохраняем данные правого канала
fwrite(buf+2, 1, 2, fp_r);
}
fclose(fp);
fclose(fp_l);
fclose(fp_r);
return 1;
}
int main()
{
char file[] = "./mediadata/NocturneNo2inEflat_44.1k_s16le.pcm";
if (pcm16le_split(file)) {
printf("Операция прошла успешно!!\n");
} else {
printf("Операция не удалась!!\n");
}
}
Из кода видно, что в данных PCM16LE значения выборок для левого и правого каналов разделяются. Каждое значение выборки занимает два байта пространства. После выполнения кода данные NocturneNo2inEflat_44.1k_s16le.pcm будут разделены на два монофонических канала: output_l.pcm для левого канала и output_r.pcm для правого канала. output_r.pcm: данные правого канала
Примечание: в этой статье частота выборки звуковых образцов составляет 44100 Гц, а формат выборки — 16LE. «16» означает, что разрядность выборки составляет 16 бит. Поскольку 1 байт = 8 бит, один канал выборки занимает 2 байта. «LE» обозначает Little Endian, то есть способ хранения 2-байтовых значений выборки, при котором старший байт находится по старшему адресу.
//
// Эта программа может уменьшить громкость левого канала данных PCM16LE с двухканальным звуком.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pcm16le_halfvolumeleft(const char *file)
{
if (file == NULL) {
printf("Исходный файл пуст!\n");
return 0;
}
FILE *fp = fopen(file, "rb+");
if (fp == NULL) {
printf("Не удалось открыть исходный файл!\n");
return 0;
}
FILE *fp1 = fopen("./output/output_halfleft.pcm", "wb+");
if (fp1 == NULL) {
printf("Ошибка открытия или создания файла!\n");
return 0;
}
unsigned char buf[4] = {0};
while (!feof(fp)) {
// Считываем один раз значение выборки, поскольку оно 16-битное, считываем 4 байта
// Интервал между значениями выборки левого и правого каналов
// Первые два байта — это значение выборки для левого канала, вторые два байта — для правого канала
fread(buf, 1, 4, fp);
// Принудительно преобразуем первые два байта (значение выборки левого канала) в тип short
short *sample = (short *)buf;
// Делим значение выборки левого канала на два
*sample /= 2;
// Записываем уменьшенное значение выборки левого канала в файл
fwrite(sample, 1, 2, fp1);
// Записываем исходное значение выборки правого канала в файл
fwrite(buf + 2, 1, 2, fp1);
}
fclose(fp);
fclose(fp1);
return 1;
}
int main()
{
char file[] = "./mediadata/NocturneNo2inEflat_44.1k_s16le.pcm";
if (pcm16le_halfvolumeleft(file)) {
printf("Операция прошла успешно!!\n");
} else {
printf("Операция не удалась!!\n");
}
}
Из исходного кода видно, что эта программа считывает 2-байтное значение выборки левого канала после чтения данных и рассматривает его как переменную типа short в языке C. После деления значения на 2 результат записывается обратно в файл PCM.
Примечание: в этой статье частота выборки звуковых образцов составляет 44100 Гц, а формат выборки — 16LE. «16» означает, что разрядность выборки составляет 16 бит. Поскольку 1 байт = 8 бит, один канал выборки занимает 2 байта. «LE» обозначает Little Endian, то есть способ хранения 2-байтовых значений выборки, при котором старший байт находится по старшему адресу.
//
//Эта программа может увеличить скорость звука данных PCM16LE с двухканальной выборкой в два раза.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pcm16le_doublespeed(const char *file)
{
if (file == NULL) {
printf("Исходный PCM-файл пуст!\n");
return 0;
}
FILE *fp = fopen(file, "rb+");
if (fp == NULL) {
printf("Не удалось открыть исходный PCM-файл!\n");
return 0;
}
FILE *fp1 = fopen("./output/output_doublespeed.pcm", "wb+");
if (fp1 == NULL) {
printf("Ошибка открытия или создания файла!\n");
return 0;
}
int count = 0; // Количество выборок
unsigned char buf[4] = {0};
while ( !feof(fp) ) {
//Считываем одно значение выборки, так как оно 16-разрядное, считываем 4 байта
//Интервал между значениями выборки левого и правого каналов
//Первые два байта - это значение выборки для левого канала, вторые два байта - для правого канала
fread(buf, 1, 4, fp);
//Записываем только чётные значения выборки
if (count % 2 == 0) {
//Сохраняем данные левого канала, одно значение выборки 16 разрядов, два байта
fwrite(buf, 1, 2, fp1);
//Сохраняем данные правого канала, одно значение выборки 16 разрядов, два байта
fwrite(buf + 2, 1, 2, fp1);
}
count++;
}
fclose(fp);
fclose(fp1);
return 1;
}
int main()
{
char file[] = "./mediadata/NocturneNo2inEflat_44.1k_s16le.pcm";
if (pcm16le_doublespeed(file)) {
printf("Операция прошла успешно!!\n");
} else {
printf("Операция не удалась!!\n");
}
}
Из исходного кода можно увидеть, что эта программа сохраняет только значения выборки чётных точек каждого канала после считывания данных. После обработки исходный 22-секундный звук становится 11-секундным. Скорость воспроизведения звука увеличивается вдвое, и высота тона также значительно повышается.
Примечание: в этой статье частота выборки звуковых образцов составляет 44100 Гц, а формат выборки — 16LE. «16» означает, что разрядность выборки составляет 16 бит. Поскольку 1 байт = 8 бит, один канал выборки занимает 2 байта. «LE» обозначает Little Endian, то есть способ хранения 2-байтовых значений выборки, при котором старший байт находится по старшему адресу.
//
//Эта функция может преобразовать данные PCM16LE с двухканальной выборкой в 8-битные данные PCM.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int pcm16le_to_pcm8(const char *file)
{
if (file == NULL) {
printf("Исходный PCM-файл пуст!\n");
return 0;
}
FILE *fp = fopen(file, "rb+");
if (fp == NULL) {
printf("Не удалось открыть исходный PCM-файл!\n");
return 0;
}
FILE *fp1 = fopen("./output/pcm16le_to_pcm8.pcm", "wb+");
if (fp1 == NULL) {
printf("Ошибка открытия или создания файла!\n");
return 0;
}
unsigned char buf[4] = {0};
while ( !feof(fp) ) {
//Считываем одно значение выборки, так как оно 16-разрядное, считываем 4 байта
//Интервал между значениями выборки левого и правого каналов
//Первые два байта - это значение выборки для левого канала, вторые два байта - для правого канала
fread(buf, 1, 4, fp);
//Принудительное преобразование первых двух байтов (значение выборки левого канала) в short-тип, потому что short-тип имеет длину 2 байта
short *sample = (short *)buf;
//Правый сдвиг на 8 разрядов, эквивалентный делению на 256 (2 в степени 8)
...
``` ```
// Получаем значение pcm16 (типа short) по модулю при делении на 256,
// это будет использоваться как значение pcm8 для выборки.
unsigned char pcm8 = (*sample) >> 8;
// Поскольку диапазон значений типа short составляет от -32768 до 32767,
// после выполнения предыдущего шага результат будет находиться в диапазоне от -128 до 127.
// Поэтому для преобразования в тип unsigned char необходимо добавить 128,
// диапазон значений unsigned char составляет от 0 до 255.
pcm8 = pcm8 + 128;
// Записываем значение выборки для левого канала.
fwrite(&pcm8, 1, 1, fp1);
// Преобразуем первые два байта (значение выборки для правого канала) в тип short принудительно.
sample = (short *)(buf + 2);
pcm8 = (*sample) >> 8;
// Из диапазона от -128 до 127 получаем диапазон от 0 до 128.
pcm8 = pcm8 + 128;
// Записываем значение выборки для правого канала.
fwrite(&pcm8, 1, 1, fp1);
}
fclose(fp);
fclose(fp1);
return 1;
Диапазон значений данных с выборкой формата PCM16LE составляет от –32 768 до 32 767, а диапазон значений данных с выборкой формата PCM8 — от 0 до 255. Поэтому преобразование данных формата PCM16LE в формат PCM8 происходит в два этапа: сначала значения от –32 768 до 32 767 преобразуются в значения от –128 до 127, затем значения от –128 до 127 преобразуются в значения от 0 до 255. В этой программе данные с 16-битной выборкой хранятся в переменной типа short, а данные с 8-битной выборкой — в переменной типа unsigned char.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )