1b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian/* 2b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * 4b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 5b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 6b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 7b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 8b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 9b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian */ 10b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 11b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Decode With Drops Example 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ========================= 13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This is an example utility which drops a series of frames, as specified 15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// on the command line. This is useful for observing the error recovery 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// features of the codec. 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Usage 19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ----- 20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This example adds a single argument to the `simple_decoder` example, 21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// which specifies the range or pattern of frames to drop. The parameter is 22b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// parsed as follows: 23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Dropping A Range Of Frames 25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// -------------------------- 26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// To drop a range of frames, specify the starting frame and the ending 27b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frame to drop, separated by a dash. The following command will drop 28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frames 5 through 10 (base 1). 29b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// $ ./decode_with_drops in.ivf out.i420 5-10 31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Dropping A Pattern Of Frames 34b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ---------------------------- 35b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// To drop a pattern of frames, specify the number of frames to drop and 36b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// the number of frames after which to repeat the pattern, separated by 37b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// a forward-slash. The following command will drop 3 of 7 frames. 38b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Specifically, it will decode 4 frames, then drop 3 frames, and then 39b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// repeat. 40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 41b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// $ ./decode_with_drops in.ivf out.i420 3/7 42b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 43b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 44b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Extra Variables 45b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// --------------- 46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This example maintains the pattern passed on the command line in the 47b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `n`, `m`, and `is_range` variables: 48b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 49b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 50b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Making The Drop Decision 51b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ------------------------ 52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// The example decides whether to drop the frame based on the current 53b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frame number, immediately before decoding the frame. 54b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 55b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h> 56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdlib.h> 57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <string.h> 58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define VPX_CODEC_DISABLE_COMPAT 1 60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vp8dx.h" 62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vpx_decoder.h" 63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 64b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./tools_common.h" 65b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./video_reader.h" 66b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vpx_config.h" 67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const char *exec_name; 69b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 70b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid usage_exit() { 71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fprintf(stderr, "Usage: %s <infile> <outfile> <N-M|N/M>\n", exec_name); 72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exit(EXIT_FAILURE); 73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint main(int argc, char **argv) { 76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_cnt = 0; 77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian FILE *outfile = NULL; 78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const VpxInterface *decoder = NULL; 80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoReader *reader = NULL; 81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const VpxVideoInfo *info = NULL; 82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int n = 0; 83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int m = 0; 84b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int is_range = 0; 85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian char *nptr = NULL; 86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exec_name = argv[0]; 88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (argc != 4) 90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Invalid number of arguments."); 91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian reader = vpx_video_reader_open(argv[1]); 93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!reader) 94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for reading.", argv[1]); 95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!(outfile = fopen(argv[2], "wb"))) 97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for writing.", argv[2]); 98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian n = strtol(argv[3], &nptr, 0); 100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian m = strtol(nptr + 1, NULL, 0); 101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian is_range = (*nptr == '-'); 102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!n || !m || (*nptr != '-' && *nptr != '/')) 103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Couldn't parse pattern %s.\n", argv[3]); 104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info = vpx_video_reader_get_info(reader); 106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); 108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!decoder) 109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Unknown input codec."); 110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); 112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0)) 114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize decoder."); 115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (vpx_video_reader_read_frame(reader)) { 117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_image_t *img = NULL; 119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size_t frame_size = 0; 120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int skip; 121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const unsigned char *frame = vpx_video_reader_get_frame(reader, 122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian &frame_size); 123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) 124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to decode frame."); 125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++frame_cnt; 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian skip = (is_range && frame_cnt >= n && frame_cnt <= m) || 129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (!is_range && m - (frame_cnt - 1) % m <= n); 130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!skip) { 132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('.', stdout); 133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) 135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_img_write(img, outfile); 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } else { 137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('X', stdout); 138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fflush(stdout); 141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Processed %d frames.\n", frame_cnt); 144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_destroy(&codec)) 145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec."); 146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", 148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info->frame_width, info->frame_height, argv[2]); 149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_video_reader_close(reader); 151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fclose(outfile); 152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return EXIT_SUCCESS; 154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 155