| 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
|
|
|