Decoding е процес на преобразуване на компресиран медиен поток в некомпресиран формат, подходящ за извеждане на екран и високоговорители. В мобилните устройства декодирането се извършва или програмно чрез CPU, или хардуерно чрез специализирани блокове на GPU и DSP. Според данни на MDN Web Docs (2026), съвременните кодеци компресират потока 100–500 пъти, а декодирането възстановява оригиналното качество без загуби при правилен избор на профил на компресия.
Основни положения
Decoding е процес на преобразуване на компресирани цифрови данни обратно в оригиналния некомпресиран формат. В контекста на медиите, декодирането възстановява видео кадри от компресирания битов поток, създаден от енкодера. Без декодиране потребителят не може да види видео или да чуе аудио, тъй като всички съвременни медийни формати използват компресия за спестяване на честотна лента и дисково пространство.
Типичен видео поток във формат H.264 с битрейт 5 Mbps заема 100 пъти по-малко място от некомпресиран RGB поток с подобна резолюция. Алгоритъмът за декодиране трябва да възстанови всеки кадър обратно до оригиналната резолюция и цветово пространство, следвайки спецификацията на кодека в обратен ред спрямо кодирането. За целта декодерът обработва вътрешнокадрови (I-frame) и междукадрови (P-frame, B-frame) данни.
На мобилни устройства декодирането може да се извършва както на CPU, така и на специални хардуерни блокове. Съвременните SoC от Apple (серия A), Qualcomm (Snapdragon) и MediaTek (Dimensity) съдържат вградени декодери за всички популярни формати. Видео процесорът поема тежката работа по обратната дискретна косинусова трансформация и компенсация на движението, освобождавайки CPU за други задачи.
Процесът на декодиране се състои от няколко последователни етапа, които обръщат стъпките на кодиране. Първо от битовия поток се извличат заглавките и параметрите на компресия — профил, ниво, резолюция, цветово пространство. След това декодерът последователно обработва компресираните макроблокове, прилагайки към тях обратни трансформации.
Първи етап — извличане на ентропиен код. Ентропийното декодиране използва алгоритми CABAC или CAVLC за възстановяване на коефициентите на дискретната косинусова трансформация. Този етап не зависи от резолюцията на видеото — той обработва битовия поток, а не пикселите, и сложността му се определя от битрейта, а не от размера на кадъра.
Втори етап — обратно квантуване и обратна DCT. Декодерът умножава квантуваните коефициенти по стъпката на квантуване, възстановявайки приблизителните стойности на DCT коефициентите, след което прилага обратната DCT трансформация. Обратната DCT възстановява пространствените данни от честотната област, формирайки макроблок от пиксели. За хрома и лумата трансформацията се извършва независимо.
Трети етап — компенсация на движението. За P- и B-кадри декодерът използва вектори на движение, извлечени от битовия поток, и се позовава на предварително декодирани референтни кадри. Компенсацията на движението създава предиктор на текущия макроблок, към който се добавя остатъчният сигнал след обратната DCT. Резултатът — напълно възстановен кадър, готов за извеждане.
// Псевдокод на основно декодиране на видео кадър
struct DecodedFrame {
uint8_t* y_plane;
uint8_t* u_plane;
uint8_t* v_plane;
int width, height;
};
class Decoder {
public:
bool decodeNALUnit(const uint8_t* nalUnit, size_t size) {
if (!parseNALUHeader(nalUnit, size))
return false;
int sliceType = parseSliceType(nalUnit);
entropyDecode(nalUnit);
inverseQuantize();
inverseDCT();
if (sliceType != I_SLICE)
motionCompensation();
return true;
}
};
В горния пример е показана основната структура на H.264 декодер. Функцията decodeNALUnit приема NAL единица — основния блок на компресирания H.264 поток. Декодерът последователно парсира заглавката, извлича типа на слайса, прилага ентропийно декодиране, обратно квантуване и обратна DCT. За P- и B-слайсове допълнително се извършва компенсация на движението с използване на референтни кадри от буфера DPB.
Съвременните видео кодеци се различават по алгоритми за компресия, ефективност и изисквания към изчислителните ресурси. Изборът на формат пряко влияе върху размера на файла, качеството на изображението и консумацията на енергия при декодиране на мобилно устройство.
| Кодек | Година | Компресия | Хардуерна поддръжка |
|---|---|---|---|
| H.264 | 2003 | 1:100 | Всички съвременни SoC |
| H.265 | 2013 | 1:200 | Apple A8+, Snapdragon 805+ |
| VP9 | 2013 | 1:180 | Snapdragon 820+, Exynos |
| AV1 | 2018 | 1:300 | Apple A17+, Snapdragon 8 Gen 2+ |
H.264 е най-разпространеният видео кодек, поддържан от всички мобилни устройства. Основното му предимство е универсалността: всеки Android смартфон и iPhone могат да декодират H.264 хардуерно. Въпреки това, при еднакъв битрейт, H.264 губи по качество в сравнение с по-модерните кодеци H.265 и AV1, изисквайки 30–50% повече битрейт за аналогично визуално качество.
H.265 осигурява двойно по-добра компресия в сравнение с H.264 при същото качество. Декодирането на H.265 изисква по-мощен хардуерен блок: VideoToolbox на iOS поддържа H.265 от iPhone 6 (A8) нататък, а Android устройствата — от Snapdragon 805 и нагоре. При избора на H.265 за мобилно приложение трябва да се има предвид, че по-старите устройства може да нямат хардуерна поддръжка и ще декодират този формат програмно, което драстично увеличава консумацията на енергия.
AV1 е отворен кодек от Alliance for Open Media, осигуряващ най-добрата компресия сред всички съвременни формати. AV1 е 30% по-ефективен от H.265 и 50% по-ефективен от H.264 при същото визуално качество. Хардуерното декодиране на AV1 се появи едва в SoC от 2023+ година: Apple A17 Pro, Qualcomm Snapdragon 8 Gen 2 и по-нови. За по-стари устройства декодирането на AV1 е възможно само програмно чрез библиотеката dav1d, което създава значително натоварване на CPU.
Изборът между програмно и хардуерно декодиране е ключово архитектурно решение при разработката на мобилен медиен плейър. Всеки подход има своите предимства и ограничения, които трябва да се вземат предвид при проектирането на приложението.
Хардуерното декодиране се извършва на специализирани блокове за обработка на видео, които консумират значително по-малко енергия от CPU при изпълнение на същата задача. Според данни на Qualcomm, хардуерният декодер за H.265 консумира 5–10 пъти по-малко енергия от програмното декодиране на CPU Snapdragon 8 Gen 1 при възпроизвеждане на 4K видео. Това е критично за мобилни устройства, където всеки миливат влияе на времето за работа с батерия.
Програмното декодиране, от друга страна, дава максимална гъвкавост. FFmpeg с библиотеката libavcodec поддържа десетки кодеци и контейнери, включително редки и остарели формати, които нямат хардуерна поддръжка. Разработчикът може да модифицира тръбопровода за декодиране, да добавя последваща обработка и филтри в движение, което е невъзможно при използване на затворени хардуерни блокове.
Програмното декодиране е оправдано в няколко сценария: при възпроизвеждане на редки формати (ProRes, DNxHD, Motion JPEG), когато е необходим точен контрол над всеки етап на обработка на кадъра, както и при декодиране на AV1 на устройства без хардуерна поддръжка. libavcodec от FFmpeg позволява декодиране на практически всеки познат формат, което го прави стандарт де факто за универсални медийни плейъри.
Ограничението на програмното декодиране е отделянето на топлина. Непрекъснатото декодиране на 4K видео на CPU може да нагрее устройството до 45–50 градуса за 10–15 минути, което води до тротлинг и намаляване на честотата на кадрите. На устройства без активно охлаждане (таблети, телефони) това е особено забележимо. Консумацията на енергия на CPU при програмно декодиране може да достигне 3–5 W срещу 0,3–0,5 W при хардуерно декодиране на същия поток.
Хардуерното декодиране е избор по подразбиране за всеки производствен медиен плейър. То осигурява стабилни 60 кадъра/с за 4K видео с минимална консумация на енергия. VideoToolbox на iOS и MediaCodec на Android предоставят собствени API за хардуерно декодиране, които автоматично избират оптималния блок за обработка в зависимост от кодека и резолюцията.
Платформените API поемат управлението на буферите за кадри (surface pool на Android, CVPixelBufferPool на iOS), синхронизацията с дисплея и оптимизацията на паметта. Разработчикът трябва само да отвори декодера с необходимите параметри и да получава готови кадри. Хардуерното декодиране поддържа целосен тръбопровод с минимално закъснение: от получаване на битовия поток до извеждане на екрана минават 5–15 ms срещу 30–80 ms при програмно декодиране.
Нека разгледаме практическата имплементация на декодиране на двете мобилни платформи. На iOS хардуерното декодиране се извършва чрез VideoToolbox, а програмното — чрез FFmpeg. На Android се използва MediaCodec за хардуерно декодиране.
@interface VideoDecoder ()
@property (nonatomic) VTDecompressionSessionRef session;
@end
@implementation VideoDecoder
- (void)setupDecoder {
CMVideoFormatDescriptionRef formatDesc;
CMVideoCodecType codecType = kCMVideoCodecType_H264;
OSStatus status = CMVideoFormatDescriptionCreate(
NULL, codecType, 1920, 1080, NULL, &formatDesc
);
VTDecompressionOutputCallbackRecord callback;
callback.decompressionOutputCallback = &decodingCallback;
VTDecompressionSessionCreate(NULL, formatDesc, NULL,
NULL, &callback, &_session);
}
- (void)decodeFrame: (uint8_t*)nalData length:(size_t)size {
CMBlockBufferRef blockBuffer;
CMBlockBufferCreateWithMemoryBlock(NULL, nalData,
size, NULL, NULL, 0, size, 0, &blockBuffer);
CMSampleBufferRef sampleBuffer;
CMSampleBufferCreate(NULL, blockBuffer, true, NULL,
NULL, NULL, 1, 0, NULL, 0, NULL, &sampleBuffer);
VTDecompressionSessionDecodeFrame(_session,
sampleBuffer, 0, NULL, 0);
}
@end
Кодът демонстрира инициализация на хардуерния декодер за H.264 на iOS. VTDecompressionSessionCreate създава сесия за декодиране, а VTCreate извиква обратно извикване при поява на готов кадър. Сесията автоматично използва хардуерния блок, ако е наличен за посочения кодек. За получаване на декодирани кадри във формат CVPixelBuffer се използва обратно извикване, което предава всеки готов кадър с минимално закъснение.
MediaCodec decoder = MediaCodec.createDecoderByType("video/avc");
MediaFormat format = MediaFormat.createVideoFormat(
"video/avc", 1920, 1080
);
format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
decoder.configure(format, surface, null, 0);
decoder.start();
ByteBuffer[] inputBuffers = decoder.getInputBuffers();
int inputIndex = decoder.dequeueInputBuffer(10000);
if (inputIndex >= 0) {
ByteBuffer buffer = inputBuffers[inputIndex];
buffer.clear();
buffer.put(nalData);
decoder.queueInputBuffer(inputIndex, 0, nalData.length, pts, 0);
}
На Android MediaCodec използва Surface за изход, а не пикселен буфер, което минимизира копирането на данни между GPU и CPU. Декодерът автоматично избира хардуерния блок (OMX компонент) въз основа на типа кодек. За H.264 се използва OMX.google.h264.decoder, който може да бъде както хардуерен, така и програмен, в зависимост от имплементацията на производителя.
Изборът на стратегия за декодиране зависи от целевата аудитория на приложението, поддържаните формати и изискванията за производителност. Оптималното решение често включва хибриден подход: хардуерно декодиране за основните формати (H.264, H.265) с програмен fallback за редки кодеци.
Ако приложението е ориентирано към максимална съвместимост — използвайте H.264, който гарантирано се декодира хардуерно на всяко устройство. За видео стрийминг услуги е оправдан H.265 с хардуерна поддръжка на устройства след 2016 година. AV1 е избор за услуги, където икономията на честотна лента е важна: YouTube, Netflix и други големи платформи активно внедряват AV1 за намаляване на разходите за CDN при запазване на качеството.
Критичен параметър — размерът на буфера на декодера. Хардуерните декодери имат фиксиран пул от буфери (обикновено 4–16 кадъра). При възпроизвеждане на поток с висок битрейт буферите могат да се препълнят, което води до пропускане на кадри. MediaCodec предоставя метода getOutputFrameRate за определяне на реалната производителност на декодера на конкретно устройство, а VideoToolbox позволява контрол на приоритета в реално време чрез kVTDecodeFrame_EnableAsynchronousDecompression.
Топлинният тротлинг е друг фактор. Дори хардуерното декодиране може да нагрее устройството при продължително възпроизвеждане на 4K HDR видео. Препоръчва се наблюдение на температурата чрез ProcessInfo на iOS и BatteryManager на Android, като се намалява качеството или резолюцията на потока при прегряване. Това е особено критично за игри и стрийминг приложения с дълги сесии на гледане.
Често задавани въпроси
Кодирането (encoding) преобразува некомпресирани данни в компресиран формат, докато декодирането (decoding) възстановява оригиналните данни от компресирания поток. Тези процеси са обратни един на друг и използват същите алгоритми: DCT, квантуване, компенсация на движението. Енкодерът извършва директното преобразуване, декодерът — обратното.
За максимална съвместимост — H.264, тъй като се декодира хардуерно на 100% от съвременните устройства. За по-добра компресия — H.265 или AV1. Изборът зависи от аудиторията: ако 80% от потребителите имат устройства от 2021+ година, H.265 ще осигури по-добро качество при по-нисък битрейт. AV1 е оправдан за флагмански устройства с хардуерна поддръжка 2023+.
Хардуерният декодер е специализиран микрочип (ASIC), проектиран изключително за декодиране. За разлика от CPU, който изпълнява декодиране чрез последователни инструкции, хардуерният блок обработва макроблоковете паралелно. Консумацията на енергия на хардуерния декодер е 5–10 пъти по-ниска, тъй като чипът работи на по-ниска честота и няма излишни етапи на конвейера.
Профилът (profile) определя набора от алгоритми за компресия, използвани от енкодера: Baseline, Main, High. Нивото (level) задава максималните параметри на потока: резолюция, битрейт, размер на буфера. За мобилни устройства се препоръчва профил High и ниво 4.1–5.2 — това е достатъчно за 1080p–4K видео с хардуерно декодиране.
На Android използвайте MediaCodecList за получаване на списък с налични кодеци и проверка кой от тях е хардуерен. На iOS проверете поддръжката чрез CMVideoFormatDescription с посочения кодек — ако VTDecompressionSessionCreate е успешна, кодекът се поддържа. За AV1 на Android проверете наличието на кодек OMX.google.aomc.decoder или неговата хардуерна версия.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също