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 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Simple Decoder 13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ============== 14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This is an example of a simple decoder loop. It takes an input file 16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// containing the compressed data (in IVF format), passes it through the 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// decoder, and writes the decompressed frames to disk. Other decoder 18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// examples build upon this one. 19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// The details of the IVF format have been elided from this example for 21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// simplicity of presentation, as IVF files will not generally be used by 22b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// your application. In general, an IVF file consists of a file header, 23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// followed by a variable number of frames. Each frame consists of a frame 24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// header followed by a variable length payload. The length of the payload 25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// is specified in the first four bytes of the frame header. The payload is 26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// the raw compressed data. 27b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Standard Includes 29b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ----------------- 30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// For decoders, you only have to include `vpx_decoder.h` and then any 31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// header files for the specific codecs you use. In this case, we're using 32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// vp8. The `VPX_CODEC_DISABLE_COMPAT` macro can be defined to ensure 33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// strict compliance with the latest SDK by disabling some backwards 34b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// compatibility features. Defining this macro is encouraged. 35b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 36b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Initializing The Codec 37b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ---------------------- 38b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// The decoder is initialized by the following code. This is an example for 39b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// the VP8 decoder, but the code is analogous for all algorithms. Replace 40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `vpx_codec_vp8_dx()` with a pointer to the interface exposed by the 41b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// algorithm you want to use. The `cfg` argument is left as NULL in this 42b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// example, because we want the algorithm to determine the stream 43b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// configuration (width/height) and allocate memory automatically. This 44b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// parameter is generally only used if you need to preallocate memory, 45b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// particularly in External Memory Allocation mode. 46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 47b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Decoding A Frame 48b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ---------------- 49b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Once the frame has been read into memory, it is decoded using the 50b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `vpx_codec_decode` function. The call takes a pointer to the data 51b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// (`frame`) and the length of the data (`frame_sz`). No application data 52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// is associated with the frame in this example, so the `user_priv` 53b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// parameter is NULL. The `deadline` parameter is left at zero for this 54b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// example. This parameter is generally only used when doing adaptive 55b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// postprocessing. 56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Codecs may produce a variable number of output frames for every call to 58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `vpx_codec_decode`. These frames are retrieved by the 59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `vpx_codec_get_frame` iterator function. The iterator variable `iter` is 60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// initialized to NULL each time `vpx_codec_decode` is called. 61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// `vpx_codec_get_frame` is called in a loop, returning a pointer to a 62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// decoded image or NULL to indicate the end of list. 63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 64b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Processing The Decoded Data 65b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// --------------------------- 66b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// In this example, we simply write the encoded data to disk. It is 67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// important to honor the image's `stride` values. 68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 69b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Cleanup 70b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// ------- 71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// The `vpx_codec_destroy` call frees any memory allocated by the codec. 72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// 73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// Error Handling 74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// -------------- 75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// This example does not special case any error return codes. If there was 76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// an error, a descriptive message is printed and the program exits. With 77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// few exeptions, vpx_codec functions return an enumerated error status, 78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// with the value `0` indicating success. 79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h> 81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdlib.h> 82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <string.h> 83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 84b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define VPX_CODEC_DISABLE_COMPAT 1 85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vp8dx.h" 87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx/vpx_decoder.h" 88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./tools_common.h" 90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./video_reader.h" 91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vpx_config.h" 92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const char *exec_name; 94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid usage_exit() { 96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); 97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exit(EXIT_FAILURE); 98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint main(int argc, char **argv) { 101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int frame_cnt = 0; 102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian FILE *outfile = NULL; 103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_ctx_t codec; 104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian VpxVideoReader *reader = NULL; 105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const VpxInterface *decoder = NULL; 106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const VpxVideoInfo *info = NULL; 107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian exec_name = argv[0]; 109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (argc != 3) 111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Invalid number of arguments."); 112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian reader = vpx_video_reader_open(argv[1]); 114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!reader) 115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for reading.", argv[1]); 116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!(outfile = fopen(argv[2], "wb"))) 118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Failed to open %s for writing.", argv[2]); 119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info = vpx_video_reader_get_info(reader); 121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); 123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!decoder) 124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die("Unknown input codec."); 125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); 127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0)) 129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to initialize decoder."); 130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (vpx_video_reader_read_frame(reader)) { 132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_codec_iter_t iter = NULL; 133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_image_t *img = NULL; 134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size_t frame_size = 0; 135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const unsigned char *frame = vpx_video_reader_get_frame(reader, 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian &frame_size); 137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) 138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to decode frame."); 139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { 141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_img_write(img, outfile); 142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ++frame_cnt; 143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Processed %d frames.\n", frame_cnt); 147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (vpx_codec_destroy(&codec)) 148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian die_codec(&codec, "Failed to destroy codec"); 149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", 151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian info->frame_width, info->frame_height, argv[2]); 152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian vpx_video_reader_close(reader); 154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian fclose(outfile); 156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 157b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return EXIT_SUCCESS; 158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 159