Merge "Adding lossless encoding example."
This commit is contained in:
Коммит
fb285bab1e
|
@ -149,6 +149,13 @@ simple_encoder.SRCS += video_common.h
|
|||
simple_encoder.SRCS += video_writer.h video_writer.c
|
||||
simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
|
||||
simple_encoder.DESCRIPTION = Simplified encoder loop
|
||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
|
||||
vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
|
||||
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
|
||||
vp9_lossless_encoder.SRCS += video_common.h
|
||||
vp9_lossless_encoder.SRCS += video_writer.h video_writer.c
|
||||
vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
|
||||
vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder
|
||||
EXAMPLES-$(CONFIG_VP8_ENCODER) += twopass_encoder.c
|
||||
twopass_encoder.SRCS += ivfenc.h ivfenc.c
|
||||
twopass_encoder.SRCS += tools_common.h tools_common.c
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
|
||||
#include "./tools_common.h"
|
||||
#include "./video_writer.h"
|
||||
|
||||
static const char *exec_name;
|
||||
|
||||
void usage_exit() {
|
||||
fprintf(stderr, "vp9_lossless_encoder: Example demonstrating VP9 lossless "
|
||||
"encoding feature. Supports raw input only.\n");
|
||||
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int encode_frame(vpx_codec_ctx_t *codec,
|
||||
vpx_image_t *img,
|
||||
int frame_index,
|
||||
int flags,
|
||||
VpxVideoWriter *writer) {
|
||||
int got_pkts = 0;
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
|
||||
flags, VPX_DL_GOOD_QUALITY);
|
||||
if (res != VPX_CODEC_OK)
|
||||
die_codec(codec, "Failed to encode frame");
|
||||
|
||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||
got_pkts = 1;
|
||||
|
||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||
if (!vpx_video_writer_write_frame(writer,
|
||||
pkt->data.frame.buf,
|
||||
pkt->data.frame.sz,
|
||||
pkt->data.frame.pts)) {
|
||||
die_codec(codec, "Failed to write compressed frame");
|
||||
}
|
||||
printf(keyframe ? "K" : ".");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
return got_pkts;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
FILE *infile = NULL;
|
||||
vpx_codec_ctx_t codec;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
int frame_count = 0;
|
||||
vpx_image_t raw;
|
||||
vpx_codec_err_t res;
|
||||
VpxVideoInfo info = {0};
|
||||
VpxVideoWriter *writer = NULL;
|
||||
const VpxInterface *encoder = NULL;
|
||||
const int fps = 30;
|
||||
|
||||
exec_name = argv[0];
|
||||
|
||||
if (argc < 5)
|
||||
die("Invalid number of arguments");
|
||||
|
||||
encoder = get_vpx_encoder_by_name("vp9");
|
||||
if (!encoder)
|
||||
die("Unsupported codec.");
|
||||
|
||||
info.codec_fourcc = encoder->fourcc;
|
||||
info.frame_width = strtol(argv[1], NULL, 0);
|
||||
info.frame_height = strtol(argv[2], NULL, 0);
|
||||
info.time_base.numerator = 1;
|
||||
info.time_base.denominator = fps;
|
||||
|
||||
if (info.frame_width <= 0 ||
|
||||
info.frame_height <= 0 ||
|
||||
(info.frame_width % 2) != 0 ||
|
||||
(info.frame_height % 2) != 0) {
|
||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||
}
|
||||
|
||||
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
|
||||
info.frame_height, 1)) {
|
||||
die("Failed to allocate image.");
|
||||
}
|
||||
|
||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||
|
||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||
if (res)
|
||||
die_codec(&codec, "Failed to get default codec config.");
|
||||
|
||||
cfg.g_w = info.frame_width;
|
||||
cfg.g_h = info.frame_height;
|
||||
cfg.g_timebase.num = info.time_base.numerator;
|
||||
cfg.g_timebase.den = info.time_base.denominator;
|
||||
|
||||
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
||||
if (!writer)
|
||||
die("Failed to open %s for writing.", argv[4]);
|
||||
|
||||
if (!(infile = fopen(argv[3], "rb")))
|
||||
die("Failed to open %s for reading.", argv[3]);
|
||||
|
||||
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
|
||||
die_codec(&codec, "Failed to initialize encoder");
|
||||
|
||||
if (vpx_codec_control_(&codec, VP9E_SET_LOSSLESS, 1))
|
||||
die_codec(&codec, "Failed to use lossless mode");
|
||||
|
||||
// Encode frames.
|
||||
while (vpx_img_read(&raw, infile)) {
|
||||
encode_frame(&codec, &raw, frame_count++, 0, writer);
|
||||
}
|
||||
|
||||
// Flush encoder.
|
||||
while (encode_frame(&codec, NULL, -1, 0, writer)) {}
|
||||
|
||||
printf("\n");
|
||||
fclose(infile);
|
||||
printf("Processed %d frames.\n", frame_count);
|
||||
|
||||
vpx_img_free(&raw);
|
||||
if (vpx_codec_destroy(&codec))
|
||||
die_codec(&codec, "Failed to destroy codec.");
|
||||
|
||||
vpx_video_writer_close(writer);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Загрузка…
Ссылка в новой задаче