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