12ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian/* 22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * 42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 82ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 92ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian */ 102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Postprocessing Decoder 122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ====================== 132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// This example adds postprocessing to the simple decoder loop. 152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Initializing Postprocessing 172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// --------------------------- 182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// You must inform the codec that you might request postprocessing at 192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// initialization time. This is done by passing the VPX_CODEC_USE_POSTPROC 202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// flag to `vpx_codec_dec_init`. If the codec does not support 212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// postprocessing, this call will return VPX_CODEC_INCAPABLE. For 222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// demonstration purposes, we also fall back to default initialization if 232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// the codec does not provide support. 242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Using Adaptive Postprocessing 262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// ----------------------------- 272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// VP6 provides "adaptive postprocessing." It will automatically select the 282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// best postprocessing filter on a frame by frame basis based on the amount 292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// of time remaining before the user's specified deadline expires. The 302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// special value 0 indicates that the codec should take as long as 312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// necessary to provide the best quality frame. This example gives the 322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// codec 15ms (15000us) to return a frame. Remember that this is a soft 332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// deadline, and the codec may exceed it doing its regular processing. In 342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// these cases, no additional postprocessing will be done. 352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// 362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Codec Specific Postprocessing Controls 372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// -------------------------------------- 382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Some codecs provide fine grained controls over their built-in 392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// postprocessors. VP8 is one example. The following sample code toggles 402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// postprocessing on and off every 15 frames. 412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <stdio.h> 432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <stdlib.h> 442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <string.h> 452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vpx/vp8dx.h" 472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vpx/vpx_decoder.h" 482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 49da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#include "../tools_common.h" 50da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#include "../video_reader.h" 512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "./vpx_config.h" 522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianstatic const char *exec_name; 542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 55da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianvoid usage_exit(void) { 562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); 572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exit(EXIT_FAILURE); 582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianint main(int argc, char **argv) { 612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int frame_cnt = 0; 622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian FILE *outfile = NULL; 632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_err_t res; 652ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VpxVideoReader *reader = NULL; 662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const VpxInterface *decoder = NULL; 672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const VpxVideoInfo *info = NULL; 682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian exec_name = argv[0]; 702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (argc != 3) 722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Invalid number of arguments."); 732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian reader = vpx_video_reader_open(argv[1]); 752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!reader) 762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Failed to open %s for reading.", argv[1]); 772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!(outfile = fopen(argv[2], "wb"))) 792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Failed to open %s for writing", argv[2]); 802ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info = vpx_video_reader_get_info(reader); 822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); 842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (!decoder) 852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die("Unknown input codec."); 862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface())); 882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian res = vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian VPX_CODEC_USE_POSTPROC); 912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (res == VPX_CODEC_INCAPABLE) 922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Postproc not supported by this decoder."); 932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (res) 952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize decoder."); 962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while (vpx_video_reader_read_frame(reader)) { 982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_image_t *img = NULL; 1002ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian size_t frame_size = 0; 1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const unsigned char *frame = vpx_video_reader_get_frame(reader, 1022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian &frame_size); 1032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian ++frame_cnt; 1052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (frame_cnt % 30 == 1) { 1072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vp8_postproc_cfg_t pp = {0, 0, 0}; 1082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) 1102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to turn off postproc."); 1112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else if (frame_cnt % 30 == 16) { 1122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vp8_postproc_cfg_t pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE, 1132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 4, 0}; 1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) 1152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to turn on postproc."); 1162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian }; 1172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian // Decode the frame with 15ms deadline 1192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 15000)) 1202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to decode frame"); 1212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { 1232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_img_write(img, outfile); 1242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 1262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian printf("Processed %d frames.\n", frame_cnt); 1282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (vpx_codec_destroy(&codec)) 1292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec"); 1302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", 1322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian info->frame_width, info->frame_height, argv[2]); 1332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian vpx_video_reader_close(reader); 1352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian 1362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian fclose(outfile); 1372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian return EXIT_SUCCESS; 1382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian} 139