Skip to content

Commit

Permalink
Start working on vp9
Browse files Browse the repository at this point in the history
  • Loading branch information
Noarkhh committed Jun 10, 2024
1 parent 9450c61 commit 608c447
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 11 deletions.
26 changes: 15 additions & 11 deletions c_src/membrane_vpx_plugin/vp8_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ void handle_destroy_state(UnifexEnv *env, State *state) {
UNIFEX_TERM create(UnifexEnv *env) {
UNIFEX_TERM result;
State *state = unifex_alloc_state(env);
// state->codec_interface = vpx_codec_vp9_dx();
state->codec_interface = vpx_codec_vp8_dx();

if (vpx_codec_dec_init(&state->codec_context, state->codec_interface, NULL,
Expand Down Expand Up @@ -51,13 +52,13 @@ size_t get_image_byte_size(const vpx_image_t *img) {
return image_size;
}

void get_raw_frame_from_image(const vpx_image_t *img,
UnifexPayload *output_frame) {
void get_output_frame_from_image(const vpx_image_t *img,
UnifexPayload *output_frame) {
const int bytes_per_pixel = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;

// Assuming that for nv12 we write all chroma data at once
const int number_of_planes = (img->fmt == VPX_IMG_FMT_NV12) ? 2 : 3;
unsigned char *output_data = output_frame->data;
unsigned char *frame_data = output_frame->data;

for (int plane = 0; plane < number_of_planes; ++plane) {
const unsigned char *buf = img->planes[plane];
Expand All @@ -66,13 +67,20 @@ void get_raw_frame_from_image(const vpx_image_t *img,

for (unsigned int y = 0; y < plane_dimensions.height; ++y) {
size_t bytes_to_write = bytes_per_pixel * plane_dimensions.width;
memcpy(output_data, buf, bytes_to_write);
memcpy(frame_data, buf, bytes_to_write);
buf += stride;
output_data += bytes_to_write;
frame_data += bytes_to_write;
}
}
}

void alloc_output_frame(UnifexEnv *env, const vpx_image_t *img,
UnifexPayload **output_frame) {
*output_frame = unifex_alloc(sizeof(UnifexPayload));
unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, get_image_byte_size(img),
*output_frame);
}

UNIFEX_TERM decode_frame(UnifexEnv *env, UnifexPayload *frame, State *state) {
vpx_codec_iter_t iter = NULL;
vpx_image_t *img = NULL;
Expand All @@ -92,12 +100,8 @@ UNIFEX_TERM decode_frame(UnifexEnv *env, UnifexPayload *frame, State *state) {
unifex_realloc(output_frames, max_frames * sizeof(*output_frames));
}

output_frames[frames_cnt] = unifex_alloc(sizeof(UnifexPayload));
const size_t output_frame_size = get_image_byte_size(img);
unifex_payload_alloc(env, UNIFEX_PAYLOAD_BINARY, output_frame_size,
output_frames[frames_cnt]);

get_raw_frame_from_image(img, output_frames[frames_cnt]);
alloc_output_frame(env, img, &output_frames[frames_cnt]);
get_output_frame_from_image(img, output_frames[frames_cnt]);
frames_cnt++;
}

Expand Down
Binary file added test/fixtures/input_vp9.ivf
Binary file not shown.
24 changes: 24 additions & 0 deletions test/fixtures/ref_vp9.raw

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions test/membrane_vpx_plugin/vp9_decoder_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule Membrane.VP9.DecoderTest do
use ExUnit.Case, async: true

import Membrane.Testing.Assertions
import Membrane.ChildrenSpec

@fixtures_dir "test/fixtures"

@tag :tmp_dir
test "Decoder decodes", %{tmp_dir: tmp_dir} do
pid =
Membrane.Testing.Pipeline.start_link_supervised!(
spec:
child(:source, %Membrane.File.Source{
location: Path.join(@fixtures_dir, "input_vp9.ivf")
})
|> child(:deserializer, Membrane.Element.IVF.Deserializer)
|> child(:decoder, Membrane.VP8.Decoder)
|> child(:sink, %Membrane.File.Sink{location: Path.join(tmp_dir, "output.vp9")})
)

assert_end_of_stream(pid, :sink, :input, 2000)
end
end

0 comments on commit 608c447

Please sign in to comment.