Index: source/libvpx/vp9_spatial_scalable_encoder.c |
=================================================================== |
--- source/libvpx/vp9_spatial_scalable_encoder.c (revision 251189) |
+++ source/libvpx/vp9_spatial_scalable_encoder.c (working copy) |
@@ -18,9 +18,11 @@ |
#include <stdlib.h> |
#include <string.h> |
#include <time.h> |
+ |
#include "./args.h" |
-#include "./ivfenc.h" |
#include "./tools_common.h" |
+#include "./video_writer.h" |
+ |
#include "vpx/svc_context.h" |
#include "vpx/vp8cx.h" |
#include "vpx/vpx_encoder.h" |
@@ -73,10 +75,10 @@ |
static const uint32_t default_kf_dist = 100; |
typedef struct { |
- char *output_filename; |
+ const char *input_filename; |
+ const char *output_filename; |
uint32_t frames_to_code; |
uint32_t frames_to_skip; |
- struct VpxInputContext input_ctx; |
} AppInput; |
static const char *exec_name; |
@@ -92,8 +94,10 @@ |
static void parse_command_line(int argc, const char **argv_, |
AppInput *app_input, SvcContext *svc_ctx, |
vpx_codec_enc_cfg_t *enc_cfg) { |
- struct arg arg; |
- char **argv, **argi, **argj; |
+ struct arg arg = {0}; |
+ char **argv = NULL; |
+ char **argi = NULL; |
+ char **argj = NULL; |
vpx_codec_err_t res; |
// initialize SvcContext with parameters that will be passed to vpx_svc_init |
@@ -160,7 +164,7 @@ |
if (argv[0] == NULL || argv[1] == 0) { |
usage_exit(); |
} |
- app_input->input_ctx.filename = argv[0]; |
+ app_input->input_filename = argv[0]; |
app_input->output_filename = argv[1]; |
free(argv); |
@@ -183,7 +187,8 @@ |
int main(int argc, const char **argv) { |
AppInput app_input = {0}; |
- FILE *outfile; |
+ VpxVideoWriter *writer = NULL; |
+ VpxVideoInfo info = {0}; |
vpx_codec_ctx_t codec; |
vpx_codec_enc_cfg_t enc_cfg; |
SvcContext svc_ctx; |
@@ -193,8 +198,7 @@ |
vpx_codec_err_t res; |
int pts = 0; /* PTS starts at 0 */ |
int frame_duration = 1; /* 1 timebase tick per frame */ |
- vpx_codec_cx_pkt_t packet = {0}; |
- packet.kind = VPX_CODEC_CX_FRAME_PKT; |
+ FILE *infile = NULL; |
memset(&svc_ctx, 0, sizeof(svc_ctx)); |
svc_ctx.log_print = 1; |
@@ -205,27 +209,36 @@ |
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) |
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h); |
- if (!(app_input.input_ctx.file = fopen(app_input.input_ctx.filename, "rb"))) |
- die("Failed to open %s for reading\n", app_input.input_ctx.filename); |
+ if (!(infile = fopen(app_input.input_filename, "rb"))) |
+ die("Failed to open %s for reading\n", app_input.input_filename); |
- if (!(outfile = fopen(app_input.output_filename, "wb"))) |
- die("Failed to open %s for writing\n", app_input.output_filename); |
- |
// Initialize codec |
if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) != |
VPX_CODEC_OK) |
die("Failed to initialize encoder\n"); |
- ivf_write_file_header(outfile, &enc_cfg, VP9_FOURCC, 0); |
+ info.codec_fourcc = VP9_FOURCC; |
+ info.time_base.numerator = enc_cfg.g_timebase.num; |
+ info.time_base.denominator = enc_cfg.g_timebase.den; |
+ if (vpx_svc_get_layer_resolution(&svc_ctx, svc_ctx.spatial_layers - 1, |
+ (unsigned int *)&info.frame_width, |
+ (unsigned int *)&info.frame_height) != |
+ VPX_CODEC_OK) { |
+ die("Failed to get output resolution"); |
+ } |
+ writer = vpx_video_writer_open(app_input.output_filename, kContainerIVF, |
+ &info); |
+ if (!writer) |
+ die("Failed to open %s for writing\n", app_input.output_filename); |
// skip initial frames |
- for (i = 0; i < app_input.frames_to_skip; ++i) { |
- read_yuv_frame(&app_input.input_ctx, &raw); |
- } |
+ for (i = 0; i < app_input.frames_to_skip; ++i) |
+ vpx_img_read(&raw, infile); |
// Encode frames |
while (frame_cnt < app_input.frames_to_code) { |
- if (read_yuv_frame(&app_input.input_ctx, &raw)) break; |
+ if (!vpx_img_read(&raw, infile)) |
+ break; |
res = vpx_svc_encode(&svc_ctx, &codec, &raw, pts, frame_duration, |
VPX_DL_REALTIME); |
@@ -234,11 +247,10 @@ |
die_codec(&codec, "Failed to encode frame"); |
} |
if (vpx_svc_get_frame_size(&svc_ctx) > 0) { |
- packet.data.frame.pts = pts; |
- packet.data.frame.sz = vpx_svc_get_frame_size(&svc_ctx); |
- ivf_write_frame_header(outfile, &packet); |
- (void)fwrite(vpx_svc_get_buffer(&svc_ctx), 1, |
- vpx_svc_get_frame_size(&svc_ctx), outfile); |
+ vpx_video_writer_write_frame(writer, |
+ vpx_svc_get_buffer(&svc_ctx), |
+ vpx_svc_get_frame_size(&svc_ctx), |
+ pts); |
} |
++frame_cnt; |
pts += frame_duration; |
@@ -246,22 +258,11 @@ |
printf("Processed %d frames\n", frame_cnt); |
- fclose(app_input.input_ctx.file); |
+ fclose(infile); |
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); |
- // rewrite the output file headers with the actual frame count, and |
- // resolution of the highest layer |
- if (!fseek(outfile, 0, SEEK_SET)) { |
- // get resolution of highest layer |
- if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(&svc_ctx, |
- svc_ctx.spatial_layers - 1, |
- &enc_cfg.g_w, |
- &enc_cfg.g_h)) { |
- die("Failed to get output resolution"); |
- } |
- ivf_write_file_header(outfile, &enc_cfg, VP9_FOURCC, frame_cnt); |
- } |
- fclose(outfile); |
+ vpx_video_writer_close(writer); |
+ |
vpx_img_free(&raw); |
// display average size, psnr |