рефераты

рефераты

 
 
рефераты рефераты

Меню

Реферат: Алгоритм сжатия видео 'pixel behaviour check' рефераты

10: Frame[I].cpCurrent := Frame[I].cpCurrent - Frame[I].cpExtent;

end;

end;

После цикла по всем элементам массива опорного кадра в полях cpCurrent элементов массива находятся значения, которые должны быть занесены в реальный кадр на экране. Собственно говоря, картинка реального кадра уже получена в опорном кадре, но данные картинки еще нужно перевести из процентных отношений в прямые значения, если они не были такими (установлен бит RatioType поля Properties заголовка видеопотока). Затем полученные прямые значения нужно перевести из YCbCr в RGB, если установлен бит ColorSpace поля Properties. Но нужно обратить внимание, что содержимое полей cpCurrent элементов массива опорного кадра ни в коем случае нельзя изменять, так как нам нужны непереведенные значения для декодирования следующего кадра. Для перевода из YCbCr в RGB необходимо извлекать из массива опорного кадра сразу по три цветовых плоскости пикселя, потому что формулам преобразования YCbCr в RGB нужны значения трех плоскостей. Поэтому процедура отображения кадра на экране будет иметь два цикла - по высоте и по ширине кадра.

// глобальные переменные

var

Header: PBCvideoHeader; // заголовок видеопотока

Frame: array of ColorPlane; // опорный кадр

FrameNum: DWord; // номер текущего кадра

procedure ShowFrame;

var

W: Word; // ширина

H: Word; // высота

I: DWord; // индекс плоскости в массиве опорного кадра

Y: Double; // значение плоскости Y

Cb: Double; // значение плоскости Cb

Cr: Double; // значение плоскости Cr

R: Byte; // значение красного цвета

G: Byte; // значение зеленого цвета

B: Byte; // значение синего цвета

begin

// в цикле рисуем все пиксели на реальном экране

// (допустим его имя VideoScreen)

for H := 1 to Header.Height do begin

for W := 1 to Header.Width do begin

I := (H-1) * Header.Width * 3 + (W-1) * 3;

// читаем значения трех цветовых плоскостей пикселя

// из соответствующих элементов массива опорного кадра

Cr := Frame[I].cpCurrent;

Y := Frame[I+1].cpCurrent;

Cb := Frame[I+2].cpCurrent;

// если значения заданы с помощью процентных

// отношений (установлен бит RatioType поля Properties),

// тогда перевести их в прямые значения

if Header.Properties and 2 <> 0 then begin

Cr := Cr * (256 / 100);

Y := Y * (256 / 100);

Cb := Cb * (256 / 100);

end;

// если прямые значения необходимо перевести

// из YCbCr в RGB (установлен бит ColorSpace поля Properties),

// тогда перевести их в RGB, иначе они уже заданы в виде RGB

if Header.Properties and 1 <> 0 then begin

R := Trunc(Y + 1.402 * (Cr - 128));

G := Trunc(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128));

B := Trunc(Y + 1.772 * (Cb - 128));

end else begin

R := Trunc(Cr);

G := Trunc(Y);

B := Trunc(Cb);

end;

// а теперь осталось занести цвет пикселя (он находится

// в переменных R, G и B) в реальный кадр на экране, где

// координаты пикселя заданы переменными W и H

// (в Canvas цвет хранится как BGR, а не как RGB)

VideoScreen.Canvas.Pixels[W-1, H-1] := (B * $10000) or (G * $100) or R;

end;

end;

// +1 кадр видеофильма показали на экране,

// и если видеопоток закончился (счетчик кадров

// достиг количества кадров в видео), тогда остановить программу

Inc(FrameNum);

if FrameNum >= Header.FrameCount then Halt;

end;

Если из приведенного кода убрать все комментарии, можно заметить, что программный код декодера небольшой. К тому же алгоритм декодирования оказывается простым и быстрым. Кстати, программный код декодера можно оптимизировать еще в более компактный, так как перестановкой проверки поля cpIndex сначала на реальный индекс (а не на 0FFFFh) можно добиться исключения одинаковых фрагментов кода, читающих поведение из общего видеопотока или набора поведений из массива поведений. Но это уже вы сами решайте, как вам будет удобнее.

За счет чего происходит сжатие

В качестве примера я взял из фильма "Шестой день" поведение красной цветовой плоскости произвольного пикселя в центральной части кадра. Всего взято 100 кадров, что равно 4 секундам фильма при скорости 25 кадров в секунду. Специально выбрал фрагмент фильма, где развивается динамичное действие. Через кадр быстро проезжает машина, а за ней появляется новая сцена с вертолетом. А теперь посмотрим, как вела себя цветовая плоскость R на протяжении 100 кадров.

185, 193, 194, 194, 192, 197, 197, 207, 207, 204, 204, 201, 201, 197, 200, 197, 208, 210, 208, 206, 209, 209, 216, 216, 216, 215, 214, 214, 214, 214, 214, 214, 217, 217, 216, 216, 215, 216, 079, 030, 028, 009, 047, 021, 008, 017, 060, 025, 024, 018, 013, 015, 015, 017, 017, 017, 017, 017, 017, 016, 016, 016, 012, 011, 015, 015, 015, 014, 005, 006, 008, 008, 008, 008, 008, 004, 011, 012, 012, 012, 012, 012, 012, 012, 012, 012, 012, 012, 012, 012, 007, 007, 006, 053, 054, 058, 053, 052, 050, 047

Здесь указаны непосредственные значения красной цветовой плоскости пикселя для каждого из 100 извлеченных кадров. Значение цветовой плоскости всегда лежит в пределах одного байта, а значит, изменяется только от 0 до 255. Как вы можете заметить, в малых значениях добавлены ведущие нули. Я сделал это для того, чтобы выровнять значения для их удобного просмотра при любом размере текстового окна.

Можно сразу заметить, что в наборе байт встречается очень мало смежных повторений одного и того же состояния цветовой плоскости, чтобы кодировать этот фрагмент любым аналогом RLE-алгоритма. Но мы-то рассматриваем фрагмент 100 представленных байт как окончательный и готовый к сжатию, поэтому не находим, что этот набор байт пригоден для эффективного RLE-сжатия. Кодировщику же не интересен сам набор байт, поскольку ему важна только разница между каждыми смежными байтами. И теперь посмотрите, как с помощью разниц набор байт начинает превращаться в эффективный для RLE-алгоритма блок. Нужно отметить, что кодировщик всегда берет разницу по модулю между каждыми смежными байтами.

000, 008, 001, 000, 002, 005, 000, 010, 000, 003, 000, 003, 000, 004, 003, 003, 011, 002, 002, 002, 003, 000, 007, 000, 000, 001, 001, 000, 000, 000, 000, 000, 003, 000, 001, 000, 001, 001, 137, 049, 002, 019, 038, 026, 013, 009, 043, 035, 001, 006, 005, 002, 000, 002, 000, 000, 000, 000, 000, 001, 000, 000, 004, 001, 004, 000, 000, 001, 009, 001, 002, 000, 000, 000, 000, 004, 007, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 005, 000, 001, 047, 001, 004, 005, 001, 002, 003

Получившийся набор состоит из 100 разниц и выглядит уже легче для визуального восприятия. Хотя еще ничего особого не произошло. Тот же самый набор байт, но выраженный через разницы между смежными байтами. Заметьте, в нем стало еще меньше повторяющихся смежных и одинаковых по значению байт. Поэтому для RLE-алгоритма новый набор байт еще не эффективен, разве что содержимое его байт занимает в битовом представлении намного меньше места.

Обратите внимание, что в первом кадре первого набора находилось значение 185, а в наборе разниц находится разница 0. В этот момент предполагалось, что мы кодируем 100 кадров не из середины фильма, а как будто они у нас будут началом отдельного закодированного фрагмента. Допустим, красная цветовая плоскость опорного кадра была заполнена значением 185, поэтому для первого кадра разница между ним и плоскостью опорного кадра равна нулю.

В заключительной фазе подготовки набора байт для RLE-алгоритма кодировщик преобразует набор разниц из прямых значений в процентные отношения. Для этого каждая разница делится на 2.56 (256 / 100) и получается разница, выраженная в процентах. Посмотрите, каким получается окончательный набор байт.

00, 03, 00, 00, 00, 01, 00, 03, 00, 01, 00, 01, 00, 01, 01, 01, 04, 00, 00, 00, 01, 00, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00, 00, 53, 19, 00, 07, 14, 10, 05, 03, 16, 13, 00, 02, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 01, 00, 00, 00, 03, 00, 00, 00, 00, 00, 00, 01, 02, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 18, 00, 01, 01, 00, 00, 01

Вы видите, какие получились маленькие значения, какое количество нулей. К слову сказать, MPEG стремится к такому же большому количеству нулей, но за счет множественных потерь информации. Но PBC-кодировщику мало достигнуто результата. В его арсенале есть еще массив поведений. Закодировав полученный набор из 100 байт аналогично RLE (PBC-алгоритм в своей основе использует метод, похожий на RLE, но несколько измененный), кодировщик начинает отыскивать в сжатом фрагменте похожие участки. Нужно сказать, что данный сжатый фрагмент представляет собой поток поведений 100 кадров красной цветовой плоскости. Когда в потоке поведений (общий видеопоток) обнаруживается более одного похожего участка, кодировщик извлекает их из потока и забрасывает в свободный элемент массива поведений, а на место извлеченных участков ставит одно единственное поведение со ссылкой (с индексом) на этот элемент массива. Помещаемые в массив похожие участки поведений называются наборами поведений. Например, в окончательном наборе байт часто повторяются "не эффективно" кодируемые участки типа (00, 01), (00, 02) и (00, 03), которые сбрасываются в массив, а вместо них в поток поведений ставится одно поведение со ссылкой на соответствующие элементы массива поведений. Естественно, участки типа (00, 01) и т.п. забрасываются в массив поведений не как значения 0 и 1, а как их PBC-сжатый вариант. Принцип заполнения массива поведений чем-то похож на LZW-сжатие.

Если кодировщик привел набор байт к удобному сжатию, то массив поведений дополнительно "сгладил" неудобные для сжатия участки. Хочу обратить ваше внимание на тот факт, что при ссылке на первые 32 элемента массива поведений в общем видеопотоке расходуется всего лишь один байт, поэтому в эти элементы желательно заносить самые "корявые" с точки зрения эффективности кодирования наборы поведений. Ссылкой на остальные элементы массива всегда расходуется два байта в видеопотоке.

Но и на этом прелести PBC-сжатия не заканчиваются. Дело в том, что поведения цветовых плоскостей многих пикселей видеокадра на протяжении многих кадров один в один похожи на цветовые плоскости соседних пикселей. Например, значения тех же самых 100 кадров красной цветовой плоскости верхнего пикселя (прямо над текущим) в точности повторяли значения текущего пикселя. Значения красной цветовой плоскости пикселя справа тоже в точности повторяли текущий пиксель, но были как бы смещены на один кадр. Машина ехала через кадр с правой стороны, поэтому первым зацепила правый пиксель, а текущий пиксель воспроизвел ту же последовательность поведений цветовой плоскости, но с запозданием в один кадр. Нечего и говорить о том, что верхний пиксель над правым почти полностью походил по поведению (все же у него имелись различия в нескольких кадрах) на правый пиксель. Сбросив в свободный элемент массива поведений 100-кадровый набор поведений текущего пикселя, кодировщик может для верхнего и текущего пикселей в общем видеопотоке указать всего лишь по одному поведению, ссылающемуся на один и тот же элемент массива поведений. В общем, можно достичь высокой степени сжатия, и это при отсутствии сложности алгоритма, отсутствии необходимости в алгоритмах компенсации движения и т.п.

И это еще не все. Когда мы рассматривали, как кодировщик готовит набор байт для сжатия, я указал самый простой вариант подготовки байт, когда кодировщик "глупо" берет и заносит в подготавливаемый набор разницы цветовой плоскости между каждым смежным кадром. PBC-алгоритм предоставляет кодировщику достаточные возможности для еще более качественной подготовки набора байт для сжатия. Самый лучший подход, когда разница берется не между двумя смежными кадрами, а между начальным и конечным кадрами изменения цветовой плоскости. Если значение цветовой плоскости начало нарастать, то кодировщик ждет кадра, в котором плоскость перестанет нарастать. За время нарастания цветовой плоскости кодировщик просто подсчитывает, сколько же кадров она нарастала, а затем в видеопоток заносит, что плоскость нарастала столько-то кадров, а изменение ее значения составило столько-то процентов. Если значение цветовой плоскости начало убывать, снова ждет окончания убывания плоскости и заносит в видеопоток, что она столько кадров убывала на столько-то процентов. Когда же плоскость не изменяется, кодировщик ждет начала любого ее изменения, а в видеопоток заносит, сколько кадров она не изменялась.

Краткая справка по PBC-сжатию

Кодирование представляет собой запись видеоинформации с помощью наблюдений за изменением значений цветовых плоскостей всех пикселей кадра относительно предыдущих кадров. Всякое изменение рассматривается как разница (по модулю) между предыдущим значением и новым. Каждое изменение упаковывается в соответствующую структуру из одного, двух или трех байт и заносится в закодированный видеопоток.

Каждый следующий кадр видео анализируется по линиям - подряд от верхней линии к нижней. В каждой линии анализируются слева-направо все пиксели линии. В каждом пикселе анализируются все его три цветовые плоскости. В итоге содержимое видеокадра рассматривается как элементарный байтовый массив, где каждый байт определяет состояние соответствующей цветовой плоскости определенного пикселя кадра.

Упакованное изменение называется поведением цветовой плоскости пикселя. В поведении содержатся сведения: что происходит с цветовой плоскостью, на какую величину изменяется ее значение и сколько кадров уходит на это изменение.

Алгоритм допускает любой подход к наблюдению за изменением цветовых плоскостей. Самый простой (и самый неэффективный) подход заключается в записи данных об изменении между двумя смежными кадрами. Для этого из байтового массива текущего кадра отнимается по модулю байтовый массив предыдущего кадра (побайтно - байт массива текущего кадра минус байт с таким же смещением массива предыдущего кадра). Получившийся массив разниц заносится в закодированный видеопоток.

Самые эффективные методы включают в себя функции тщательного отслеживания окончания фазы изменения цветовой плоскости, чтобы закодированный видеопоток представлял собой последовательность прямых линий, описывающих кривую изменения цветовой плоскости. Причем тщательностью функций отслеживания можно добиться, чтобы кривая была максимально точно смоделирована из набора прямых линий.

Отсюда можно вывести, что в поведении цветовой плоскости всегда закодирована прямая линия. Угол наклона прямой линии относительно текущего значения цветовой плоскости определяется величиной следующего изменения и количеством кадров изменения. Чем длиннее прямая линия в сторону количества кадров, тем эффективнее сжатие, но и больше вероятность цветовых потерь, так как исходная кривая не всегда лежит в пределах прямой линии.

Закодированный видеопоток состоит из заголовка, массива поведений и общего видеопотока. В заголовке содержатся сведения о размере видеокадра, скорости следования кадров в секунду, отличительных особенностях кодирования видео и начальных значениях цветовых плоскостей опорного кадра.

Алгоритмом поддерживаются цветовые пространства RGB и YCbCr. Декодирование всегда осуществляется в цветовое пространство RGB. Задание изменений цветовых плоскостей может быть сделано как в виде прямых значений, так и в виде процентных отношений. Прямое значение - это натуральная величина изменения цветовой плоскости. Процентное отношение - величина изменения, выраженная в диапазоне от 0 до 100 процентов.

Опорный кадр представляет собой одинаковый по размерам с видеокадром кадр, от которого начинается декодирование первого кадра видео. Каждая цветовая плоскость опорного кадра полностью заполнена соответствующим начальным значением из заголовка закодированного видеопотока. В результате все пиксели опорного кадра заполнены одним и тем же цветом. Этот цвет можно считать некоторым подобием цвета фона первого кадра видео.

В массиве поведений находятся часто повторяющиеся наборы поведений цветовых плоскостей пикселей. Всего массив может содержать не более 8192 наборов по 256 поведений в каждом наборе. Набор поведений представляет собой несколько следующих подряд поведений цветовой плоскости пикселя. В любом наборе допускается хранить любое количество поведений, но не более 256. В массиве поведений допускается хранить любое количество наборов, но не более 8192. Также допускается не использовать массив поведений, но даже в этом случае он обязан присутствовать в закодированном видеопотоке в виде пустого массива.

В общем видеопотоке находятся разрозненные поведения цветовых плоскостей пикселей и ссылки на уже существующие в массиве поведений наборы поведений. Разрозненное поведение представляет собой одиночное поведение, мало встречающееся среди поведений цветовых плоскостей пикселей. Ссылка на набор поведений обозначает, что для некоторой цветовой плоскости под ссылкой подразумевается целая последовательность из нескольких поведений, которая уже описана в ссылаемом наборе поведений.

Алгоритм допускает внедрять в общий видеопоток любые дополнительные данные. Такие данные называются внедренными блоками данных. Они игнорируются алгоритмом, но он имеет возможность прерывать декодирование видео и передавать эти блоки на обработку разным специальным функциям (при наличии таких), а после восстанавливать декодирование с прерванного места.

Декодирование воссоздает кадры видео по содержимому закодированного видеопотока. На основе опорного кадра и извлекаемых из видеопотока данных строится первый кадр видео. Каждый следующий кадр строится на основании содержимого текущего кадра. Декодер преобразует извлекаемые из общего видеопотока поведения в прямые линии и значение каждой цветовой плоскости пикселей кадра движется в точности по своему набору прямых линий.

Следующее поведение в общем видеопотоке всегда принадлежит той цветовой плоскости пикселя, которая достигла края своей прямой (декодер уже отрисовал для нее прямую). Поэтому в алгоритме вообще нет необходимости в указывании каких-либо координат. Как и при кодировании, каждый кадр декодируется анализом линий кадра сверху-вниз с проходом цветовых плоскостей пикселей каждой линии слева-направо. Координаты алгоритму не нужны, так как, двигаясь по пикселям линий, он следит за выполнением поведения каждой цветовой плоскости. У кого поведение закончилось (прямая линия отрисована), значит, его новое поведение находится сейчас в видеопотоке. А координаты декодеру уже известны, потому что он остановился на том месте (координатах), у кого закончилось поведение.

Список литературы

Для подготовки данной работы были использованы материалы с сайта http://www.sciteclibrary.ru


Страницы: 1, 2, 3