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 Partial Drops Example 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ========================= 13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This is an example utility which drops a series of frames (or parts of 15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frames), as specified on the command line. This is useful for observing the 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// error recovery 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_partial_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_partial_drops in.ivf out.i420 3/7 42b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 43b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Dropping Random Parts Of Frames 44b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ------------------------------- 45b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// A third argument tuple is available to split the frame into 1500 bytes pieces 46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// and randomly drop pieces rather than frames. The frame will be split at 47b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// partition boundaries where possible. The following example will seed the RNG 48b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// with the seed 123 and drop approximately 5% of the pieces. Pieces which 49b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// are depending on an already dropped piece will also be dropped. 50b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 51b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// $ ./decode_with_partial_drops in.ivf out.i420 5,123 52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 53b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Extra Variables 54b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// --------------- 55b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This example maintains the pattern passed on the command line in the 56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `n`, `m`, and `is_range` variables: 57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Making The Drop Decision 59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ------------------------ 60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// The example decides whether to drop the frame based on the current 61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// frame number, immediately before decoding the frame. 62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdarg.h> 64b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h> 65b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdlib.h> 66b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <string.h> 67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define VPX_CODEC_DISABLE_COMPAT 1 68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vpx_config.h" 69b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vp8dx.h" 70b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vpx_decoder.h" 71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define interface (vpx_codec_vp8_dx()) 72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <time.h> 73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define IVF_FILE_HDR_SZ (32) 76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define IVF_FRAME_HDR_SZ (12) 77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic unsigned int mem_get_le32(const unsigned char *mem) { 79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return (mem[3] << 24)|(mem[2] << 16)|(mem[1] << 8)|(mem[0]); 80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void die(const char *fmt, ...) { 83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian va_list ap; 84b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian va_start(ap, fmt); 86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vprintf(fmt, ap); 87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(fmt[strlen(fmt)-1] != '\n') 88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("\n"); 89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exit(EXIT_FAILURE); 90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void die_codec(vpx_codec_ctx_t *ctx, const char *s) { 93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const char *detail = vpx_codec_error_detail(ctx); 94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("%s: %s\n", s, vpx_codec_error(ctx)); 96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(detail) 97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf(" %s\n",detail); 98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exit(EXIT_FAILURE); 99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstruct parsed_header 102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian char key_frame; 104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int version; 105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian char show_frame; 106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int first_part_size; 107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}; 108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint next_packet(struct parsed_header* hdr, int pos, int length, int mtu) 110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int size = 0; 112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int remaining = length - pos; 113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Uncompressed part is 3 bytes for P frames and 10 bytes for I frames */ 114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int uncomp_part_size = (hdr->key_frame ? 10 : 3); 115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* number of bytes yet to send from header and the first partition */ 116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int remainFirst = uncomp_part_size + hdr->first_part_size - pos; 117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (remainFirst > 0) 118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (remainFirst <= mtu) 120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size = remainFirst; 122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else 124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size = mtu; 126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return size; 129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* second partition; just slot it up according to MTU */ 132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (remaining <= mtu) 133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size = remaining; 135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return size; 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return mtu; 138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid throw_packets(unsigned char* frame, int* size, int loss_rate, 141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int* thrown, int* kept) 142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned char loss_frame[256*1024]; 144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int pkg_size = 1; 145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int pos = 0; 146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int loss_pos = 0; 147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct parsed_header hdr; 148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int tmp; 149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int mtu = 1500; 150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (*size < 3) 152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return; 154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('|', stdout); 156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* parse uncompressed 3 bytes */ 157b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian tmp = (frame[2] << 16) | (frame[1] << 8) | frame[0]; 158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian hdr.key_frame = !(tmp & 0x1); /* inverse logic */ 159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian hdr.version = (tmp >> 1) & 0x7; 160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian hdr.show_frame = (tmp >> 4) & 0x1; 161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian hdr.first_part_size = (tmp >> 5) & 0x7FFFF; 162b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 163b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* don't drop key frames */ 164b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (hdr.key_frame) 165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int i; 167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *kept = *size/mtu + ((*size % mtu > 0) ? 1 : 0); /* approximate */ 168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i=0; i < *kept; i++) 169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('.', stdout); 170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return; 171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while ((pkg_size = next_packet(&hdr, pos, *size, mtu)) > 0) 174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int loss_event = ((rand() + 1.0)/(RAND_MAX + 1.0) < loss_rate/100.0); 176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (*thrown == 0 && !loss_event) 177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(loss_frame + loss_pos, frame + pos, pkg_size); 179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian loss_pos += pkg_size; 180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (*kept)++; 181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('.', stdout); 182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else 184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 185b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (*thrown)++; 186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('X', stdout); 187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pos += pkg_size; 189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(frame, loss_frame, loss_pos); 191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memset(frame + loss_pos, 0, *size - loss_pos); 192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *size = loss_pos; 193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint main(int argc, char **argv) { 196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian FILE *infile, *outfile; 197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int flags = 0, frame_cnt = 0; 199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned char file_hdr[IVF_FILE_HDR_SZ]; 200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned char frame_hdr[IVF_FRAME_HDR_SZ]; 201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned char frame[256*1024]; 202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_err_t res; 203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int n, m, mode; 204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int seed; 205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int thrown=0, kept=0; 206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int thrown_frame=0, kept_frame=0; 207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_dec_cfg_t dec_cfg = {0}; 208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (void)res; 210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Open files */ 211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(argc < 4 || argc > 6) 212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Usage: %s <infile> <outfile> [-t <num threads>] <N-M|N/M|L,S>\n", 213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian argv[0]); 214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian char *nptr; 216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int arg_num = 3; 217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (argc == 6 && strncmp(argv[arg_num++], "-t", 2) == 0) 218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian dec_cfg.threads = strtol(argv[arg_num++], NULL, 0); 219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian n = strtol(argv[arg_num], &nptr, 0); 220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian mode = (*nptr == '\0' || *nptr == ',') ? 2 : (*nptr == '-') ? 1 : 0; 221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian m = strtol(nptr+1, NULL, 0); 223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if((!n && !m) || (*nptr != '-' && *nptr != '/' && 224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *nptr != '\0' && *nptr != ',')) 225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Couldn't parse pattern %s\n", argv[3]); 226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian seed = (m > 0) ? m : (unsigned int)time(NULL); 228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian srand(seed);thrown_frame = 0; 229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Seed: %u\n", seed); 230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Threads: %d\n", dec_cfg.threads); 231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(!(infile = fopen(argv[1], "rb"))) 232b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for reading", argv[1]); 233b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(!(outfile = fopen(argv[2], "wb"))) 234b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for writing", argv[2]); 235b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Read file header */ 237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(!(fread(file_hdr, 1, IVF_FILE_HDR_SZ, infile) == IVF_FILE_HDR_SZ 238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian && file_hdr[0]=='D' && file_hdr[1]=='K' && file_hdr[2]=='I' 239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian && file_hdr[3]=='F')) 240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("%s is not an IVF file.", argv[1]); 241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Using %s\n",vpx_codec_iface_name(interface)); 243b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Initialize codec */ 244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian flags = VPX_CODEC_USE_ERROR_CONCEALMENT; 245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian res = vpx_codec_dec_init(&codec, interface, &dec_cfg, flags); 246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(res) 247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize decoder"); 248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Read each frame */ 251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while(fread(frame_hdr, 1, IVF_FRAME_HDR_SZ, infile) == IVF_FRAME_HDR_SZ) { 252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_sz = mem_get_le32(frame_hdr); 253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_image_t *img; 255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian frame_cnt++; 258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(frame_sz > sizeof(frame)) 259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Frame %d data too big for example code buffer", frame_sz); 260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(fread(frame, 1, frame_sz, infile) != frame_sz) 261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Frame %d failed to read complete frame", frame_cnt); 262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Decide whether to throw parts of the frame or the whole frame 264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian depending on the drop mode */ 265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian thrown_frame = 0; 266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian kept_frame = 0; 267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian switch (mode) 268b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 0: 270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (m - (frame_cnt-1)%m <= n) 271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian frame_sz = 0; 273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 275b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 1: 276b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (frame_cnt >= n && frame_cnt <= m) 277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 278b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian frame_sz = 0; 279b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case 2: 282b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian throw_packets(frame, &frame_sz, n, &thrown_frame, &kept_frame); 283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian default: break; 285b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (mode < 2) 287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (frame_sz == 0) 289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('X', stdout); 291b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian thrown_frame++; 292b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian else 294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian { 295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian putc('.', stdout); 296b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian kept_frame++; 297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian thrown += thrown_frame; 300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian kept += kept_frame; 301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fflush(stdout); 302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Decode the frame */ 303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(vpx_codec_decode(&codec, frame, frame_sz, NULL, 0)) 304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to decode frame"); 305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Write decoded data to disk */ 307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while((img = vpx_codec_get_frame(&codec, &iter))) { 308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int plane, y; 309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for(plane=0; plane < 3; plane++) { 311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned char *buf =img->planes[plane]; 312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for(y=0; y < (plane ? (img->d_h + 1) >> 1 : img->d_h); y++) { 314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian (void) fwrite(buf, 1, (plane ? (img->d_w + 1) >> 1 : img->d_w), 315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian outfile); 316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian buf += img->stride[plane]; 317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Processed %d frames.\n",frame_cnt); 322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if(vpx_codec_destroy(&codec)) 323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec"); 324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fclose(outfile); 326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fclose(infile); 327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return EXIT_SUCCESS; 328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 329