OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 // codec 15ms (15000us) to return a frame. Remember that this is a soft | 32 // codec 15ms (15000us) to return a frame. Remember that this is a soft |
33 // deadline, and the codec may exceed it doing its regular processing. In | 33 // deadline, and the codec may exceed it doing its regular processing. In |
34 // these cases, no additional postprocessing will be done. | 34 // these cases, no additional postprocessing will be done. |
35 // | 35 // |
36 // Codec Specific Postprocessing Controls | 36 // Codec Specific Postprocessing Controls |
37 // -------------------------------------- | 37 // -------------------------------------- |
38 // Some codecs provide fine grained controls over their built-in | 38 // Some codecs provide fine grained controls over their built-in |
39 // postprocessors. VP8 is one example. The following sample code toggles | 39 // postprocessors. VP8 is one example. The following sample code toggles |
40 // postprocessing on and off every 15 frames. | 40 // postprocessing on and off every 15 frames. |
41 | 41 |
42 #include <stdarg.h> | |
43 #include <stdio.h> | 42 #include <stdio.h> |
44 #include <stdlib.h> | 43 #include <stdlib.h> |
45 #include <string.h> | 44 #include <string.h> |
| 45 |
46 #define VPX_CODEC_DISABLE_COMPAT 1 | 46 #define VPX_CODEC_DISABLE_COMPAT 1 |
47 #include "./vpx_config.h" | 47 |
48 #include "vpx/vp8dx.h" | 48 #include "vpx/vp8dx.h" |
49 #include "vpx/vpx_decoder.h" | 49 #include "vpx/vpx_decoder.h" |
50 #define interface (vpx_codec_vp8_dx()) | |
51 | 50 |
| 51 #include "./tools_common.h" |
| 52 #include "./video_reader.h" |
| 53 #include "./vpx_config.h" |
52 | 54 |
53 #define IVF_FILE_HDR_SZ (32) | 55 static const char *exec_name; |
54 #define IVF_FRAME_HDR_SZ (12) | |
55 | 56 |
56 static unsigned int mem_get_le32(const unsigned char *mem) { | 57 void usage_exit() { |
57 return (mem[3] << 24)|(mem[2] << 16)|(mem[1] << 8)|(mem[0]); | 58 fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); |
| 59 exit(EXIT_FAILURE); |
58 } | 60 } |
59 | 61 |
60 static void die(const char *fmt, ...) { | 62 int main(int argc, char **argv) { |
61 va_list ap; | 63 int frame_cnt = 0; |
| 64 FILE *outfile = NULL; |
| 65 vpx_codec_ctx_t codec; |
| 66 vpx_codec_err_t res; |
| 67 VpxVideoReader *reader = NULL; |
| 68 const VpxInterface *decoder = NULL; |
| 69 const VpxVideoInfo *info = NULL; |
62 | 70 |
63 va_start(ap, fmt); | 71 exec_name = argv[0]; |
64 vprintf(fmt, ap); | 72 |
65 if(fmt[strlen(fmt)-1] != '\n') | 73 if (argc != 3) |
66 printf("\n"); | 74 die("Invalid number of arguments."); |
67 exit(EXIT_FAILURE); | 75 |
| 76 reader = vpx_video_reader_open(argv[1]); |
| 77 if (!reader) |
| 78 die("Failed to open %s for reading.", argv[1]); |
| 79 |
| 80 if (!(outfile = fopen(argv[2], "wb"))) |
| 81 die("Failed to open %s for writing", argv[2]); |
| 82 |
| 83 info = vpx_video_reader_get_info(reader); |
| 84 |
| 85 decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc); |
| 86 if (!decoder) |
| 87 die("Unknown input codec."); |
| 88 |
| 89 printf("Using %s\n", vpx_codec_iface_name(decoder->interface())); |
| 90 |
| 91 res = vpx_codec_dec_init(&codec, decoder->interface(), NULL, |
| 92 VPX_CODEC_USE_POSTPROC); |
| 93 if (res == VPX_CODEC_INCAPABLE) |
| 94 die_codec(&codec, "Postproc not supported by this decoder."); |
| 95 |
| 96 if (res) |
| 97 die_codec(&codec, "Failed to initialize decoder."); |
| 98 |
| 99 while (vpx_video_reader_read_frame(reader)) { |
| 100 vpx_codec_iter_t iter = NULL; |
| 101 vpx_image_t *img = NULL; |
| 102 size_t frame_size = 0; |
| 103 const unsigned char *frame = vpx_video_reader_get_frame(reader, |
| 104 &frame_size); |
| 105 |
| 106 ++frame_cnt; |
| 107 |
| 108 if (frame_cnt % 30 == 1) { |
| 109 vp8_postproc_cfg_t pp = {0, 0, 0}; |
| 110 |
| 111 if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) |
| 112 die_codec(&codec, "Failed to turn off postproc."); |
| 113 } else if (frame_cnt % 30 == 16) { |
| 114 vp8_postproc_cfg_t pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE, |
| 115 4, 0}; |
| 116 if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) |
| 117 die_codec(&codec, "Failed to turn on postproc."); |
| 118 }; |
| 119 |
| 120 // Decode the frame with 15ms deadline |
| 121 if (vpx_codec_decode(&codec, frame, frame_size, NULL, 15000)) |
| 122 die_codec(&codec, "Failed to decode frame"); |
| 123 |
| 124 while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { |
| 125 vpx_img_write(img, outfile); |
| 126 } |
| 127 } |
| 128 |
| 129 printf("Processed %d frames.\n", frame_cnt); |
| 130 if (vpx_codec_destroy(&codec)) |
| 131 die_codec(&codec, "Failed to destroy codec"); |
| 132 |
| 133 printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n", |
| 134 info->frame_width, info->frame_height, argv[2]); |
| 135 |
| 136 vpx_video_reader_close(reader); |
| 137 |
| 138 fclose(outfile); |
| 139 return EXIT_SUCCESS; |
68 } | 140 } |
69 | |
70 static void die_codec(vpx_codec_ctx_t *ctx, const char *s) { | |
71 const char *detail = vpx_codec_error_detail(ctx); | |
72 | |
73 printf("%s: %s\n", s, vpx_codec_error(ctx)); | |
74 if(detail) | |
75 printf(" %s\n",detail); | |
76 exit(EXIT_FAILURE); | |
77 } | |
78 | |
79 | |
80 int main(int argc, char **argv) { | |
81 FILE *infile, *outfile; | |
82 vpx_codec_ctx_t codec; | |
83 int flags = 0, frame_cnt = 0; | |
84 unsigned char file_hdr[IVF_FILE_HDR_SZ]; | |
85 unsigned char frame_hdr[IVF_FRAME_HDR_SZ]; | |
86 unsigned char frame[256*1024]; | |
87 vpx_codec_err_t res; | |
88 | |
89 (void)res; | |
90 /* Open files */ | |
91 if(argc!=3) | |
92 die("Usage: %s <infile> <outfile>\n", argv[0]); | |
93 if(!(infile = fopen(argv[1], "rb"))) | |
94 die("Failed to open %s for reading", argv[1]); | |
95 if(!(outfile = fopen(argv[2], "wb"))) | |
96 die("Failed to open %s for writing", argv[2]); | |
97 | |
98 /* Read file header */ | |
99 if(!(fread(file_hdr, 1, IVF_FILE_HDR_SZ, infile) == IVF_FILE_HDR_SZ | |
100 && file_hdr[0]=='D' && file_hdr[1]=='K' && file_hdr[2]=='I' | |
101 && file_hdr[3]=='F')) | |
102 die("%s is not an IVF file.", argv[1]); | |
103 | |
104 printf("Using %s\n",vpx_codec_iface_name(interface)); | |
105 /* Initialize codec */ | |
106 res = vpx_codec_dec_init(&codec, interface, NULL, | |
107 VPX_CODEC_USE_POSTPROC); | |
108 if(res == VPX_CODEC_INCAPABLE) { | |
109 printf("NOTICE: Postproc not supported by %s\n", | |
110 vpx_codec_iface_name(interface)); | |
111 res = vpx_codec_dec_init(&codec, interface, NULL, flags); | |
112 } | |
113 if(res) | |
114 die_codec(&codec, "Failed to initialize decoder"); | |
115 | |
116 /* Read each frame */ | |
117 while(fread(frame_hdr, 1, IVF_FRAME_HDR_SZ, infile) == IVF_FRAME_HDR_SZ) { | |
118 int frame_sz = mem_get_le32(frame_hdr); | |
119 vpx_codec_iter_t iter = NULL; | |
120 vpx_image_t *img; | |
121 | |
122 | |
123 frame_cnt++; | |
124 if(frame_sz > sizeof(frame)) | |
125 die("Frame %d data too big for example code buffer", frame_sz); | |
126 if(fread(frame, 1, frame_sz, infile) != frame_sz) | |
127 die("Frame %d failed to read complete frame", frame_cnt); | |
128 | |
129 #if CONFIG_VP9_DECODER | |
130 if(frame_cnt%30 == 1) { | |
131 vp8_postproc_cfg_t pp = {0, 0, 0}; | |
132 | |
133 if(vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) | |
134 die_codec(&codec, "Failed to turn off postproc"); | |
135 } else if(frame_cnt%30 == 16) { | |
136 vp8_postproc_cfg_t pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE,
4, 0}; | |
137 | |
138 if(vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp)) | |
139 die_codec(&codec, "Failed to turn on postproc"); | |
140 }; | |
141 #endif | |
142 /* Decode the frame with 15ms deadline */ | |
143 if(vpx_codec_decode(&codec, frame, frame_sz, NULL, 15000)) | |
144 die_codec(&codec, "Failed to decode frame"); | |
145 | |
146 /* Write decoded data to disk */ | |
147 while((img = vpx_codec_get_frame(&codec, &iter))) { | |
148 unsigned int plane, y; | |
149 | |
150 for(plane=0; plane < 3; plane++) { | |
151 unsigned char *buf =img->planes[plane]; | |
152 | |
153 for(y=0; y < (plane ? (img->d_h + 1) >> 1 : img->d_h); y++) { | |
154 (void) fwrite(buf, 1, (plane ? (img->d_w + 1) >> 1 : img->d_
w), | |
155 outfile); | |
156 buf += img->stride[plane]; | |
157 } | |
158 } | |
159 } | |
160 } | |
161 printf("Processed %d frames.\n",frame_cnt); | |
162 if(vpx_codec_destroy(&codec)) | |
163 die_codec(&codec, "Failed to destroy codec"); | |
164 | |
165 fclose(outfile); | |
166 fclose(infile); | |
167 return EXIT_SUCCESS; | |
168 } | |
OLD | NEW |