working av1 and h264 decoder, h265 is fucked up for some reason and idk why??

This commit is contained in:
l1npengtul
2025-11-14 18:01:47 +09:00
parent 3848c416d8
commit ab2bedfbf1
211 changed files with 400 additions and 165 deletions
Generated
+6 -6
View File
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1755020227,
"narHash": "sha256-gGmm+h0t6rY88RPTaIm3su95QvQIVjAJx558YUG4Id8=",
"lastModified": 1762482733,
"narHash": "sha256-g/da4FzvckvbiZT075Sb1/YDNDr+tGQgh4N8i5ceYMg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "695d5db1b8b20b73292501683a524e0bd79074fb",
"rev": "e1ebeec86b771e9d387dd02d82ffdc77ac753abc",
"type": "github"
},
"original": {
@@ -62,11 +62,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1755052812,
"narHash": "sha256-Tjw2YP7Hz8+ibE8wJ+Ps65vh1lzAe5ozmoo9sdQ7rGg=",
"lastModified": 1762828736,
"narHash": "sha256-RxtFHWZpKwVcWHhx88E2NhWuBbgYVqIoIDynGs5FoJs=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "433023cba5f4fa66b8b0fdbb8f91d420c9cc2527",
"rev": "8d5baa5628f6dbd7ce6beca3c299bae27755204c",
"type": "github"
},
"original": {
+11 -13
View File
@@ -5,8 +5,7 @@
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs =
{
outputs = {
self,
nixpkgs,
rust-overlay,
@@ -14,8 +13,7 @@
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
system: let
pkgs = import nixpkgs {
inherit system;
overlays = [rust-overlay.overlays.default];
@@ -36,12 +34,12 @@
];
}
);
in
{
in {
formatter = pkgs.alejandra;
devShells.default = rustshell {
packages = [
packages =
[
rustbin
]
++ (with pkgs; [
@@ -63,7 +61,7 @@
pipewire
rustup
gcc
ffmpeg-full
ffmpeg_8-full
nasm
libGL
flite
@@ -86,17 +84,17 @@
xvidcore
soxr
libvdpau
jetbrains.rust-rover
gmp
openapv
svt-av1
]);
env.RUST_SRC_PATH = "${rustbin}/lib/rustlib/src/rust/library";
env.LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
shellHook =
let
shellHook = let
pathToRustProject = "/project/component[@name='RustProjectSettings']";
in
''
in ''
echo "WONDERHOOOOOY!!!!"
xmlstarlet edit --inplace --update "${pathToRustProject}/option[@name='explicitPathToStdlib']/@value" --value "${rustbin}/lib/rustlib/src/rust/library" .idea/workspace.xml
xmlstarlet edit --inplace --update "${pathToRustProject}/option[@name='toolchainHomeDirectory']/@value" --value "${rustbin}/bin" .idea/workspace.xml
+1 -1
View File
@@ -47,7 +47,7 @@ pub trait CodecAsync: Codec {
async fn set_format_async(&self, format: CameraFormat) -> Result<(), NokhwaError>;
fn set_config_async(&mut self, config: Self::Config) -> Result<(), NokhwaError> {
self.set_config(config)
self.set_config(&config)
}
fn send_item_async(&mut self, input: Self::Input<'_>) -> Result<(), NokhwaError>;
+14 -2
View File
@@ -14,10 +14,10 @@
* limitations under the License.
*/
use crate::frame_format::{CustomFrameFormat, FrameFormat};
use std::fmt::Debug;
use thiserror::Error;
use crate::pixel_destination::PixelDestination;
use crate::types::Backends;
use std::fmt::Debug;
use thiserror::Error;
pub type NokhwaResult<T> = Result<T, NokhwaError>;
@@ -85,7 +85,19 @@ pub enum NokhwaError {
DecoderDestinationHintRequired,
#[error("Decoder already deinitialized. Unusable, please make a new decoder.")]
DecoderAlreadyDeinitialized,
#[error(
"Decoder requires more data to process - not actual error - please send more data to decode: {0}"
)]
DecoderNeedsMoreData(String),
}
impl NokhwaError {
#[must_use]
pub fn is_needs_more(&self) -> bool {
matches!(self, NokhwaError::DecoderNeedsMoreData(_))
}
}
//
// pub enum InitializeError {}
//
+40 -14
View File
@@ -90,11 +90,31 @@ pub struct FrameBuffer<'a> {
impl<'a> FrameBuffer<'a> {
/// Creates a new buffer with a [`&[u8]`].
#[must_use]
#[inline]
pub fn new(buffer: Cow<'a, [u8]>, metadata: Option<Metadata>) -> Self {
Self { buffer, metadata }
}
#[must_use]
pub fn from_buffer(buffer: &'a [u8], metadata: Option<Metadata>) -> Self {
FrameBuffer {
buffer: Cow::Borrowed(buffer),
metadata,
}
}
#[must_use]
pub fn from_cow(buffer: Cow<'a, [u8]>, metadata: Option<Metadata>) -> Self {
FrameBuffer { buffer, metadata }
}
#[must_use]
pub fn from_vec(buffer: Vec<u8>, metadata: Option<Metadata>) -> Self {
FrameBuffer {
buffer: Cow::Owned(buffer),
metadata,
}
}
/// Get the data of this buffer.
#[must_use]
pub fn buffer(&'a self) -> &'a [u8] {
@@ -147,22 +167,28 @@ impl Deref for FrameBuffer<'_> {
}
}
impl From<Vec<u8>> for FrameBuffer<'_> {
fn from(value: Vec<u8>) -> Self {
let buffer = Cow::Owned(value);
FrameBuffer {
buffer,
metadata: None,
}
}
}
impl<'a> From<&'a [u8]> for FrameBuffer<'a> {
fn from(value: &'a [u8]) -> Self {
let buffer = Cow::Borrowed(value);
FrameBuffer {
buffer,
buffer: Cow::Borrowed(value),
metadata: None,
}
}
}
impl From<Vec<u8>> for FrameBuffer<'static> {
fn from(value: Vec<u8>) -> Self {
FrameBuffer {
buffer: Cow::Owned(value),
metadata: None,
}
}
}
impl<'a> From<Cow<'a, [u8]>> for FrameBuffer<'a> {
fn from(value: Cow<'a, [u8]>) -> Self {
FrameBuffer {
buffer: value,
metadata: None,
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ ffmpeg = [ "ffmpeg-the-third" ]
yuyv = ["dcv-color-primitives", "yuv"]
mjpeg = ["zune-jpeg", "zune-core"]
luma = ["nokhwa-iter-extensions", "itermore"]
# static = ["ffmpeg-the-third/static"]
static = ["ffmpeg-the-third/static"]
#async = []
[dependencies]
+232 -43
View File
@@ -3,8 +3,8 @@ use ffmpeg_the_third::codec::{Context, Id};
use ffmpeg_the_third::color::{Range, Space};
use ffmpeg_the_third::decoder::{Video, find};
use ffmpeg_the_third::ffi::{
AVCodecID, AVCodecParameters, AVPacketSideData, AVPixelFormat, av_frame_alloc,
av_image_fill_arrays, av_packet_side_data_free, avcodec_parameters_alloc,
AVCodecID, AVCodecParameters, AVMediaType, AVPacketSideData, AVPixelFormat, AVRational,
av_frame_alloc, av_image_fill_arrays, av_packet_side_data_free, avcodec_parameters_alloc,
avcodec_parameters_free,
};
use ffmpeg_the_third::format::Pixel as FfmpegPixel;
@@ -53,8 +53,20 @@ fn create_video(config: &FfmpegConfig) -> Result<Video, NokhwaError> {
))
})?;
let frame_rate = AVRational {
num: config.frame_rate.numerator(),
den: config.frame_rate.denominator(),
};
let codec_i32 = unsafe { transmute::<AVCodecID, i32>(AVCodecID::from(id)) };
let intermediate_config = IntermediateDecoderConfig {
config: config.ffmpeg_codec_low_level.clone(),
resolution: config.resolution,
frame_rate,
format: codec_i32,
};
video
.set_parameters(config.ffmpeg_codec_low_level.clone())
.set_parameters(intermediate_config)
.map_err(|why| NokhwaError::DecoderInvalidConfiguration(why.to_string()))?;
let threading_kind = config.parallelism.behavior;
@@ -120,12 +132,8 @@ pub struct FfmpegOutputMeta<'a> {
pub timestamp: Option<i64>,
pub pts: Option<i64>,
pub is_key: bool,
pub is_corrupt: bool,
pub is_empty: bool,
pub is_top_first: bool,
pub is_interlaced: bool,
pub has_palatte_changed: bool,
pub color_space: Space,
pub color_range: Range,
@@ -144,19 +152,25 @@ pub struct FfmpegDecoder {
decoder: Video,
sws: ScalerContext,
config: FfmpegConfig,
last_used_format: FfmpegPixel,
last_used_out_format: FfmpegPixel,
last_used_in_format: FfmpegPixel,
}
impl FfmpegDecoder {
pub fn new(config: FfmpegConfig) -> Result<Self, NokhwaError> {
let decoder = create_video(&config)?;
let sws = create_sws(&config, decoder.format(), decoder.format())?;
let last_used_format = decoder.format();
let last_used_in_format = match decoder.format() {
FfmpegPixel::None => FfmpegPixel::RGB24,
px => px,
};
let last_used_out_format = FfmpegPixel::RGB24;
let sws = create_sws(&config, last_used_in_format, last_used_out_format)?;
Ok(FfmpegDecoder {
decoder,
sws,
config,
last_used_format,
last_used_out_format,
last_used_in_format,
})
}
@@ -187,8 +201,12 @@ impl Decoder for FfmpegDecoder {
fn set_config(&mut self, config: Self::Config) -> Result<(), NokhwaError> {
self.decoder = create_video(&config)?;
self.sws = create_sws(&config, self.decoder.format(), self.last_used_format)?;
let last_used_in_format = match self.decoder.format() {
FfmpegPixel::None => FfmpegPixel::RGB24,
px => px,
};
self.sws = create_sws(&config, last_used_in_format, self.last_used_out_format)?;
self.last_used_in_format = last_used_in_format;
self.config = config;
Ok(())
}
@@ -202,9 +220,6 @@ impl Decoder for FfmpegDecoder {
let buffer = buffer.as_mut();
let dest_as_ffmpeg = convert_destination_pixel_format_to_av_pxfmt(destination_format);
if self.last_used_format != dest_as_ffmpeg {
self.sws = create_sws(&self.config, self.decoder.format(), self.last_used_format)?;
}
let packet = Packet::borrow(to_decode.buffer());
self.decoder
@@ -216,9 +231,14 @@ impl Decoder for FfmpegDecoder {
self.decoder.width(),
self.decoder.width(),
);
self.decoder
.receive_frame(&mut frame)
.map_err(|why| NokhwaError::Decoder(why.to_string()))?;
if let Err(why) = self.decoder.receive_frame(&mut frame) {
if let ffmpeg_the_third::util::error::Error::Other { errno: 11 } = why {
return Err(NokhwaError::DecoderNeedsMoreData(why.to_string()));
} else {
return Err(NokhwaError::Decoder(why.to_string()));
}
}
let receiver_avframe = unsafe { av_frame_alloc() };
let dest_resolution = self
@@ -226,10 +246,10 @@ impl Decoder for FfmpegDecoder {
.ffmpeg_scaler_low_level
.destionation_resolution
.unwrap_or(self.config.resolution);
let av_pixel_format: AVPixelFormat = dest_as_ffmpeg.into();
unsafe {
(*receiver_avframe).width = dest_resolution.width() as i32;
(*receiver_avframe).height = dest_resolution.height() as i32;
let av_pixel_format: AVPixelFormat = dest_as_ffmpeg.into();
(*receiver_avframe).format = av_pixel_format as i32;
}
let imgbuf = unsafe {
@@ -237,7 +257,7 @@ impl Decoder for FfmpegDecoder {
(&mut (*receiver_avframe).data) as *mut *mut u8,
(&mut (*receiver_avframe).linesize) as *mut i32,
buffer.as_ptr(),
self.decoder.format().into(),
av_pixel_format,
dest_resolution.width() as i32,
dest_resolution.height() as i32,
1,
@@ -250,19 +270,31 @@ impl Decoder for FfmpegDecoder {
}
let mut receiver_frame = unsafe { frame::Video::wrap(receiver_avframe) };
// remake swscontext in case we are being gooned
let new_in_format = match frame.format() {
FfmpegPixel::None => {
return Err(NokhwaError::Decoder(
"Received None format from ffmpeg buffer. Invalid - cannot use sws".to_string(),
));
}
fmt => fmt,
};
if new_in_format != self.last_used_in_format
|| receiver_frame.format() != self.last_used_out_format
{
self.sws = create_sws(&self.config, new_in_format, receiver_frame.format())?;
self.last_used_in_format = new_in_format;
self.last_used_out_format = receiver_frame.format();
}
self.sws
.run(&frame, &mut receiver_frame)
.map_err(|why| NokhwaError::Decoder(why.to_string()))?;
let metadata = receiver_frame.metadata().to_owned();
let timestamp = receiver_frame.timestamp();
let pts = receiver_frame.pts();
let is_key = receiver_frame.is_key();
let is_corrupt = receiver_frame.is_corrupt();
let is_empty = unsafe { receiver_frame.is_empty() };
let is_top_first = receiver_frame.is_top_first();
let is_interlaced = receiver_frame.is_interlaced();
let has_palatte_changed = receiver_frame.has_palette_changed();
let color_space = receiver_frame.color_space();
let color_range = receiver_frame.color_range();
let color_primaries = receiver_frame.color_primaries();
@@ -278,12 +310,8 @@ impl Decoder for FfmpegDecoder {
metadata,
timestamp,
pts,
is_key,
is_corrupt,
is_empty,
is_top_first,
is_interlaced,
has_palatte_changed,
color_space,
color_range,
color_primaries,
@@ -408,6 +436,7 @@ where
#[derive(Clone, Debug, Default)]
pub struct FfmpegDecoderConfig {
pub codec_tag: Option<u32>,
pub bit_rate: Option<i64>,
pub profile: Option<i32>,
pub level: Option<i32>,
@@ -425,53 +454,71 @@ pub struct FfmpegDecoderConfig {
pub extra_data: Option<SideData<u8>>,
}
impl AsPtr<AVCodecParameters> for FfmpegDecoderConfig {
#[derive(Clone, Debug)]
struct IntermediateDecoderConfig {
pub(crate) config: FfmpegDecoderConfig,
pub(crate) resolution: Resolution,
pub(crate) frame_rate: AVRational,
pub(crate) format: i32,
}
impl AsPtr<AVCodecParameters> for IntermediateDecoderConfig {
fn as_ptr(&self) -> *const AVCodecParameters {
let parameters = unsafe { avcodec_parameters_alloc() };
unsafe {
if let Some(bit_rate) = self.bit_rate {
(*parameters).width = self.resolution.width() as i32;
(*parameters).height = self.resolution.height() as i32;
(*parameters).format = self.format;
(*parameters).codec_type = AVMediaType::AVMEDIA_TYPE_VIDEO;
(*parameters).framerate = self.frame_rate;
if let Some(codec_tag) = self.config.codec_tag {
(*parameters).codec_tag = codec_tag;
}
if let Some(bit_rate) = self.config.bit_rate {
(*parameters).bit_rate = bit_rate;
}
if let Some(profile) = self.profile {
if let Some(profile) = self.config.profile {
(*parameters).profile = profile;
}
if let Some(level) = self.level {
if let Some(level) = self.config.level {
(*parameters).level = level;
}
if let Some(aspect_ratio) = self.aspect_ratio {
if let Some(aspect_ratio) = self.config.aspect_ratio {
(*parameters).sample_aspect_ratio = aspect_ratio.into();
}
if let Some(field_order) = self.field_order {
if let Some(field_order) = self.config.field_order {
(*parameters).field_order = field_order.into();
}
if let Some(color_range) = self.color_range {
if let Some(color_range) = self.config.color_range {
(*parameters).color_range = color_range.into();
}
if let Some(color_primaries) = self.color_primaries {
if let Some(color_primaries) = self.config.color_primaries {
(*parameters).color_primaries = color_primaries.into();
}
if let Some(color_transfer) = self.color_transfer_characteristics {
if let Some(color_transfer) = self.config.color_transfer_characteristics {
(*parameters).color_trc = color_transfer.into();
}
if let Some(chroma_location) = self.chroma_location {
if let Some(chroma_location) = self.config.chroma_location {
(*parameters).chroma_location = chroma_location.into();
}
if let Some(coded_side_data) = self.coded_side_data {
if let Some(coded_side_data) = self.config.coded_side_data {
(*parameters).coded_side_data = coded_side_data.pointer.as_ptr();
(*parameters).nb_coded_side_data = coded_side_data.length as i32;
}
if let Some(extra_data) = self.extra_data {
if let Some(extra_data) = self.config.extra_data {
(*parameters).extradata = extra_data.pointer.as_ptr();
(*parameters).extradata_size = extra_data.length as i32;
}
@@ -604,4 +651,146 @@ const fn is_little_endian() -> bool {
}
#[cfg(test)]
mod test {}
mod test {
use ffmpeg_the_third::{codec::Context, format::input, media::Type, threading::Config};
use image::{ImageFormat, Rgb};
use nokhwa_core::{
decoder::Decoder,
frame_buffer::FrameBuffer,
frame_format::FrameFormat,
types::{FrameRate, Resolution},
};
use crate::ffmpeg::{
FfmpegConfig, FfmpegDecoder, FfmpegDecoderConfig, FfmpegScalerConfig, Parallelism,
};
#[test]
pub fn test_h264() {
ffmpeg_the_third::init().unwrap();
let file = "test_images/ffmpeg/h264/test.h264";
let output_dir = "test_images/ffmpeg/h264/out";
let decoder_cfg = FfmpegConfig {
custom_frame_format_map: None,
frame_format: FrameFormat::AVC1,
resolution: Resolution::new(498, 348),
frame_rate: FrameRate::from_fps(30),
parallelism: Parallelism::default(),
ffmpeg_codec_low_level: FfmpegDecoderConfig::default(),
ffmpeg_scaler_low_level: FfmpegScalerConfig::default(),
side_data_check_list: Vec::default(),
};
let mut decoder = FfmpegDecoder::new(decoder_cfg).unwrap();
let mut ictx = input(file).unwrap();
for maybe_frame in ictx.packets() {
let (_stream, packet) = maybe_frame.unwrap();
let decoded =
decoder.decode::<Rgb<u8>>(FrameBuffer::from_buffer(packet.data().unwrap(), None));
match decoded {
Ok(decoded) => {
let index = packet.position();
decoded
.save_with_format(format!("{output_dir}/{index}.png"), ImageFormat::Png)
.unwrap();
}
Err(why) => {
if why.is_needs_more() {
continue;
} else {
panic!("aaa {why}");
}
}
}
}
}
#[test]
pub fn test_h265() {
ffmpeg_the_third::init().unwrap();
let file = "test_images/ffmpeg/h265/out.h265";
let output_dir = "test_images/ffmpeg/h265/out";
let decoder_cfg = FfmpegConfig {
custom_frame_format_map: None,
frame_format: FrameFormat::H265,
resolution: Resolution::new(498, 348),
frame_rate: FrameRate::from_fps(30),
parallelism: Parallelism::default(),
ffmpeg_codec_low_level: FfmpegDecoderConfig::default(),
ffmpeg_scaler_low_level: FfmpegScalerConfig::default(),
side_data_check_list: Vec::default(),
};
let mut decoder = FfmpegDecoder::new(decoder_cfg).unwrap();
let mut ictx = input(file).unwrap();
for maybe_frame in ictx.packets() {
let (_stream, packet) = maybe_frame.unwrap();
let decoded =
decoder.decode::<Rgb<u8>>(FrameBuffer::from_buffer(packet.data().unwrap(), None));
match decoded {
Ok(decoded) => {
let index = packet.position();
decoded
.save_with_format(format!("{output_dir}/{index}.png"), ImageFormat::Png)
.unwrap();
}
Err(why) => {
if why.is_needs_more() {
continue;
} else {
panic!("aaa {why}");
}
}
}
}
}
#[test]
pub fn test_av1() {
ffmpeg_the_third::init().unwrap();
let file = "test_images/ffmpeg/av1/test.ivf";
let output_dir = "test_images/ffmpeg/av1/out";
let decoder_cfg = FfmpegConfig {
custom_frame_format_map: None,
frame_format: FrameFormat::AV1,
resolution: Resolution::new(320, 320),
frame_rate: FrameRate::from_fps(10),
parallelism: Parallelism::default(),
ffmpeg_codec_low_level: FfmpegDecoderConfig::default(),
ffmpeg_scaler_low_level: FfmpegScalerConfig::default(),
side_data_check_list: Vec::default(),
};
let mut decoder = FfmpegDecoder::new(decoder_cfg).unwrap();
let mut ictx = input(file).unwrap();
for maybe_frame in ictx.packets() {
let (_stream, packet) = maybe_frame.unwrap();
let decoded =
decoder.decode::<Rgb<u8>>(FrameBuffer::from_buffer(packet.data().unwrap(), None));
match decoded {
Ok(decoded) => {
let index = packet.position();
decoded
.save_with_format(format!("{output_dir}/{index}.png"), ImageFormat::Png)
.unwrap();
}
Err(why) => {
if why.is_needs_more() {
continue;
} else {
panic!("aaa {why}");
}
}
}
}
}
}
+2 -2
View File
@@ -1,8 +1,8 @@
#[cfg(feature = "ffmpeg")]
pub mod ffmpeg;
#[cfg(feature = "luma")]
pub mod luma;
#[cfg(feature = "mjpeg")]
pub mod mjpeg;
#[cfg(feature = "yuyv")]
pub mod yuv;
#[cfg(feature = "luma")]
pub mod luma;
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Some files were not shown because too many files have changed in this diff Show More