1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Simple Decoder 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan// ============== 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This is an example of a simple decoder loop. It takes an input file 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan// containing the compressed data (in IVF format), passes it through the 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan// decoder, and writes the decompressed frames to disk. Other decoder 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan// examples build upon this one. 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan// The details of the IVF format have been elided from this example for 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan// simplicity of presentation, as IVF files will not generally be used by 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan// your application. In general, an IVF file consists of a file header, 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan// followed by a variable number of frames. Each frame consists of a frame 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan// header followed by a variable length payload. The length of the payload 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan// is specified in the first four bytes of the frame header. The payload is 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan// the raw compressed data. 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Standard Includes 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan// ----------------- 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan// For decoders, you only have to include `vpx_decoder.h` and then any 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan// header files for the specific codecs you use. In this case, we're using 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan// vp8. The `VPX_CODEC_DISABLE_COMPAT` macro can be defined to ensure 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan// strict compliance with the latest SDK by disabling some backwards 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan// compatibility features. Defining this macro is encouraged. 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Initializing The Codec 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan// ---------------------- 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan// The decoder is initialized by the following code. This is an example for 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan// the VP8 decoder, but the code is analogous for all algorithms. Replace 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan// `vpx_codec_vp8_dx()` with a pointer to the interface exposed by the 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan// algorithm you want to use. The `cfg` argument is left as NULL in this 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan// example, because we want the algorithm to determine the stream 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan// configuration (width/height) and allocate memory automatically. This 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan// parameter is generally only used if you need to preallocate memory, 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan// particularly in External Memory Allocation mode. 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Decoding A Frame 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan// ---------------- 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Once the frame has been read into memory, it is decoded using the 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan// `vpx_codec_decode` function. The call takes a pointer to the data 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan// (`frame`) and the length of the data (`frame_sz`). No application data 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan// is associated with the frame in this example, so the `user_priv` 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan// parameter is NULL. The `deadline` parameter is left at zero for this 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan// example. This parameter is generally only used when doing adaptive 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan// postprocessing. 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Codecs may produce a variable number of output frames for every call to 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan// `vpx_codec_decode`. These frames are retrieved by the 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan// `vpx_codec_get_frame` iterator function. The iterator variable `iter` is 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan// initialized to NULL each time `vpx_codec_decode` is called. 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan// `vpx_codec_get_frame` is called in a loop, returning a pointer to a 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan// decoded image or NULL to indicate the end of list. 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Processing The Decoded Data 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan// --------------------------- 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan// In this example, we simply write the encoded data to disk. It is 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan// important to honor the image's `stride` values. 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Cleanup 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan// ------- 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan// The `vpx_codec_destroy` call frees any memory allocated by the codec. 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Error Handling 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan// -------------- 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This example does not special case any error return codes. If there was 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan// an error, a descriptive message is printed and the program exits. With 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan// few exeptions, vpx_codec functions return an enumerated error status, 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan// with the value `0` indicating success. 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h> 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <string.h> 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define VPX_CODEC_DISABLE_COMPAT 1 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vp8dx.h" 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_decoder.h" 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./tools_common.h" 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./video_reader.h" 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_config.h" 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan 93233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const char *exec_name; 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan 95233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid usage_exit() { 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan exit(EXIT_FAILURE); 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan 100233d2500723e5594f3e7c70896ffeeef32b9c950ywanint main(int argc, char **argv) { 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan int frame_cnt = 0; 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan FILE *outfile = NULL; 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_ctx_t codec; 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan VpxVideoReader *reader = NULL; 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan const VpxInterface *decoder = NULL; 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan const VpxVideoInfo *info = NULL; 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan exec_name = argv[0]; 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (argc != 3) 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan die("Invalid number of arguments."); 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan reader = vpx_video_reader_open(argv[1]); 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!reader) 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan die("Failed to open %s for reading.", argv[1]); 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!(outfile = fopen(argv[2], "wb"))) 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan die("Failed to open %s for writing.", argv[2]); 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan info = vpx_video_reader_get_info(reader); 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!decoder) 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan die("Unknown input codec."); 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0)) 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan die_codec(&codec, "Failed to initialize decoder."); 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (vpx_video_reader_read_frame(reader)) { 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iter_t iter = NULL; 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_image_t *img = NULL; 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t frame_size = 0; 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned char *frame = vpx_video_reader_get_frame(reader, 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan &frame_size); 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan die_codec(&codec, "Failed to decode frame."); 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_img_write(img, outfile); 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++frame_cnt; 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Processed %d frames.\n", frame_cnt); 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vpx_codec_destroy(&codec)) 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan die_codec(&codec, "Failed to destroy codec"); 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan info->frame_width, info->frame_height, argv[2]); 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_video_reader_close(reader); 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(outfile); 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan return EXIT_SUCCESS; 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 159