1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dezhihuang-AVDataProcess

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
README.md 22 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 20:22 473eed1

Перевод текста на русский язык:

// Именно строка «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.

Преобразование данных пикселей формата RGB24 в данные пикселей формата YUV420P

Эта программа реализует формулу преобразования RGB в YUV:

  • Y = 0.299 * R + 0.587 * G + 0.114 * B
  • U = -0.147 * R - 0.289 * G + 0.463 * B
  • V = 0.615 * R - 0.515 * G - 0.100 * B

Способ вызова:

./rgb24_to_yuv420p ./mediadata/lena_256x256_rgb24.rgb 256 256



Внимание:

    1. Формат RGB24 использует Packed, формат YUV420P использует Planar.
    1. U, V в горизонтальном и вертикальном направлениях имеют вдвое меньше выборок, чем Y.


Создание тестовой диаграммы RGB24

Программа rgb24_colorbar.cpp выводит девять цветов спектра: красный, оранжевый, жёлтый, зелёный, голубой, синий, фиолетовый, белый и чёрный.

Результат вывода выглядит следующим образом:



Анализ исходного потока видео H.264

Исходный поток 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, чтобы приёмник отбросил этот блок.


Разделение данных PCM16LE для левого и правого каналов аудио

Примечание: частота дискретизации звука в этой статье составляет 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: данные правого канала

Уменьшение громкости левого канала в аудиоданных с двухканальной выборкой PCM16LE в два раза

Примечание: в этой статье частота выборки звуковых образцов составляет 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.

Увеличение скорости звука в данных PCM16LE с двухканальной выборкой в два раза

Примечание: в этой статье частота выборки звуковых образцов составляет 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-секундным. Скорость воспроизведения звука увеличивается вдвое, и высота тона также значительно повышается.

Преобразование данных PCM16LE с двухканальной выборкой в данные PCM8

Примечание: в этой статье частота выборки звуковых образцов составляет 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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/dezhihuang-AVDataProcess.git
git@api.gitlife.ru:oschina-mirror/dezhihuang-AVDataProcess.git
oschina-mirror
dezhihuang-AVDataProcess
dezhihuang-AVDataProcess
master