Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: source/libvpx/examples/vp8_set_maps.c

Issue 181493009: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 26 matching lines...) Expand all
37 // 37 //
38 // The active map is cleared on frame 44. 38 // The active map is cleared on frame 44.
39 // 39 //
40 // Observing The Effects 40 // Observing The Effects
41 // --------------------- 41 // ---------------------
42 // Use the `simple_decoder` example to decode this sample, and observe 42 // Use the `simple_decoder` example to decode this sample, and observe
43 // the change in the image at frames 22, 33, and 44. 43 // the change in the image at frames 22, 33, and 44.
44 44
45 #include <stdio.h> 45 #include <stdio.h>
46 #include <stdlib.h> 46 #include <stdlib.h>
47 #include <stdarg.h>
48 #include <string.h> 47 #include <string.h>
48
49 #define VPX_CODEC_DISABLE_COMPAT 1 49 #define VPX_CODEC_DISABLE_COMPAT 1
50 #include "vpx/vp8cx.h"
50 #include "vpx/vpx_encoder.h" 51 #include "vpx/vpx_encoder.h"
51 #include "vpx/vp8cx.h"
52 #define interface (vpx_codec_vp8_cx())
53 #define fourcc 0x30385056
54 52
55 #define IVF_FILE_HDR_SZ (32) 53 #include "./tools_common.h"
56 #define IVF_FRAME_HDR_SZ (12) 54 #include "./video_writer.h"
57 55
58 static void mem_put_le16(char *mem, unsigned int val) { 56 static const char *exec_name;
59 mem[0] = val; 57
60 mem[1] = val>>8; 58 void usage_exit() {
59 fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
60 exit(EXIT_FAILURE);
61 } 61 }
62 62
63 static void mem_put_le32(char *mem, unsigned int val) { 63 static void set_roi_map(const vpx_codec_enc_cfg_t *cfg,
64 mem[0] = val; 64 vpx_codec_ctx_t *codec) {
65 mem[1] = val>>8; 65 unsigned int i;
66 mem[2] = val>>16; 66 vpx_roi_map_t roi = {0};
67 mem[3] = val>>24; 67
68 roi.rows = cfg->g_h / 16;
69 roi.cols = cfg->g_w / 16;
70
71 roi.delta_q[0] = 0;
72 roi.delta_q[1] = -2;
73 roi.delta_q[2] = -4;
74 roi.delta_q[3] = -6;
75
76 roi.delta_lf[0] = 0;
77 roi.delta_lf[1] = 1;
78 roi.delta_lf[2] = 2;
79 roi.delta_lf[3] = 3;
80
81 roi.static_threshold[0] = 1500;
82 roi.static_threshold[1] = 1000;
83 roi.static_threshold[2] = 500;
84 roi.static_threshold[3] = 0;
85
86 roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols);
87 for (i = 0; i < roi.rows * roi.cols; ++i)
88 roi.roi_map[i] = i % 4;
89
90 if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi))
91 die_codec(codec, "Failed to set ROI map");
92
93 free(roi.roi_map);
68 } 94 }
69 95
70 static void die(const char *fmt, ...) { 96 static void set_active_map(const vpx_codec_enc_cfg_t *cfg,
71 va_list ap; 97 vpx_codec_ctx_t *codec) {
98 unsigned int i;
99 vpx_active_map_t map = {0};
72 100
73 va_start(ap, fmt); 101 map.rows = cfg->g_h / 16;
74 vprintf(fmt, ap); 102 map.cols = cfg->g_w / 16;
75 if(fmt[strlen(fmt)-1] != '\n') 103
76 printf("\n"); 104 map.active_map = (uint8_t *)malloc(map.rows * map.cols);
77 exit(EXIT_FAILURE); 105 for (i = 0; i < map.rows * map.cols; ++i)
106 map.active_map[i] = i % 2;
107
108 if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
109 die_codec(codec, "Failed to set active map");
110
111 free(map.active_map);
78 } 112 }
79 113
80 static void die_codec(vpx_codec_ctx_t *ctx, const char *s) { 114 static void unset_active_map(const vpx_codec_enc_cfg_t *cfg,
81 const char *detail = vpx_codec_error_detail(ctx); 115 vpx_codec_ctx_t *codec) {
116 vpx_active_map_t map = {0};
82 117
83 printf("%s: %s\n", s, vpx_codec_error(ctx)); 118 map.rows = cfg->g_h / 16;
84 if(detail) 119 map.cols = cfg->g_w / 16;
85 printf(" %s\n",detail); 120 map.active_map = NULL;
86 exit(EXIT_FAILURE); 121
122 if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
123 die_codec(codec, "Failed to set active map");
87 } 124 }
88 125
89 static int read_frame(FILE *f, vpx_image_t *img) { 126 static void encode_frame(vpx_codec_ctx_t *codec,
90 size_t nbytes, to_read; 127 vpx_image_t *img,
91 int res = 1; 128 int frame_index,
129 VpxVideoWriter *writer) {
130 vpx_codec_iter_t iter = NULL;
131 const vpx_codec_cx_pkt_t *pkt = NULL;
132 const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
133 VPX_DL_GOOD_QUALITY);
134 if (res != VPX_CODEC_OK)
135 die_codec(codec, "Failed to encode frame");
92 136
93 to_read = img->w*img->h*3/2; 137 while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
94 nbytes = fread(img->planes[0], 1, to_read, f); 138 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
95 if(nbytes != to_read) { 139 const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
96 res = 0; 140 if (!vpx_video_writer_write_frame(writer,
97 if(nbytes > 0) 141 pkt->data.frame.buf,
98 printf("Warning: Read partial frame. Check your width & height!\n"); 142 pkt->data.frame.sz,
143 pkt->data.frame.pts)) {
144 die_codec(codec, "Failed to write compressed frame");
145 }
146
147 printf(keyframe ? "K" : ".");
148 fflush(stdout);
99 } 149 }
100 return res; 150 }
101 }
102
103 static void write_ivf_file_header(FILE *outfile,
104 const vpx_codec_enc_cfg_t *cfg,
105 int frame_cnt) {
106 char header[32];
107
108 if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
109 return;
110 header[0] = 'D';
111 header[1] = 'K';
112 header[2] = 'I';
113 header[3] = 'F';
114 mem_put_le16(header+4, 0); /* version */
115 mem_put_le16(header+6, 32); /* headersize */
116 mem_put_le32(header+8, fourcc); /* headersize */
117 mem_put_le16(header+12, cfg->g_w); /* width */
118 mem_put_le16(header+14, cfg->g_h); /* height */
119 mem_put_le32(header+16, cfg->g_timebase.den); /* rate */
120 mem_put_le32(header+20, cfg->g_timebase.num); /* scale */
121 mem_put_le32(header+24, frame_cnt); /* length */
122 mem_put_le32(header+28, 0); /* unused */
123
124 (void) fwrite(header, 1, 32, outfile);
125 }
126
127
128 static void write_ivf_frame_header(FILE *outfile,
129 const vpx_codec_cx_pkt_t *pkt)
130 {
131 char header[12];
132 vpx_codec_pts_t pts;
133
134 if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
135 return;
136
137 pts = pkt->data.frame.pts;
138 mem_put_le32(header, pkt->data.frame.sz);
139 mem_put_le32(header+4, pts&0xFFFFFFFF);
140 mem_put_le32(header+8, pts >> 32);
141
142 (void) fwrite(header, 1, 12, outfile);
143 } 151 }
144 152
145 int main(int argc, char **argv) { 153 int main(int argc, char **argv) {
146 FILE *infile, *outfile; 154 FILE *infile = NULL;
147 vpx_codec_ctx_t codec; 155 vpx_codec_ctx_t codec = {0};
148 vpx_codec_enc_cfg_t cfg; 156 vpx_codec_enc_cfg_t cfg = {0};
149 int frame_cnt = 0; 157 int frame_count = 0;
150 vpx_image_t raw; 158 vpx_image_t raw = {0};
151 vpx_codec_err_t res; 159 vpx_codec_err_t res;
152 long width; 160 VpxVideoInfo info = {0};
153 long height; 161 VpxVideoWriter *writer = NULL;
154 int frame_avail; 162 const VpxInterface *encoder = NULL;
155 int got_data; 163 const int fps = 2; // TODO(dkovalev) add command line argument
156 int flags = 0; 164 const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
157 165
158 /* Open files */ 166 exec_name = argv[0];
159 if(argc!=5)
160 die("Usage: %s <width> <height> <infile> <outfile>\n", argv[0]);
161 width = strtol(argv[1], NULL, 0);
162 height = strtol(argv[2], NULL, 0);
163 if(width < 16 || width%2 || height <16 || height%2)
164 die("Invalid resolution: %ldx%ld", width, height);
165 if(!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 1))
166 die("Faile to allocate image", width, height);
167 if(!(outfile = fopen(argv[4], "wb")))
168 die("Failed to open %s for writing", argv[4]);
169 167
170 printf("Using %s\n",vpx_codec_iface_name(interface)); 168 if (argc != 5)
169 die("Invalid number of arguments");
171 170
172 /* Populate encoder configuration */ 171 encoder = get_vpx_encoder_by_name("vp8"); // only vp8 for now
173 res = vpx_codec_enc_config_default(interface, &cfg, 0); 172 if (!encoder)
174 if(res) { 173 die("Unsupported codec.");
175 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); 174
176 return EXIT_FAILURE; 175 info.codec_fourcc = encoder->fourcc;
176 info.frame_width = strtol(argv[1], NULL, 0);
177 info.frame_height = strtol(argv[2], NULL, 0);
178 info.time_base.numerator = 1;
179 info.time_base.denominator = fps;
180
181 if (info.frame_width <= 0 ||
182 info.frame_height <= 0 ||
183 (info.frame_width % 2) != 0 ||
184 (info.frame_height % 2) != 0) {
185 die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
186 }
187
188 if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
189 info.frame_height, 1)) {
190 die("Failed to allocate image.");
191 }
192
193 printf("Using %s\n", vpx_codec_iface_name(encoder->interface()));
194
195 res = vpx_codec_enc_config_default(encoder->interface(), &cfg, 0);
196 if (res)
197 die_codec(&codec, "Failed to get default codec config.");
198
199 cfg.g_w = info.frame_width;
200 cfg.g_h = info.frame_height;
201 cfg.g_timebase.num = info.time_base.numerator;
202 cfg.g_timebase.den = info.time_base.denominator;
203 cfg.rc_target_bitrate = bitrate;
204
205 writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
206 if (!writer)
207 die("Failed to open %s for writing.", argv[4]);
208
209 if (!(infile = fopen(argv[3], "rb")))
210 die("Failed to open %s for reading.", argv[3]);
211
212 if (vpx_codec_enc_init(&codec, encoder->interface(), &cfg, 0))
213 die_codec(&codec, "Failed to initialize encoder");
214
215 while (vpx_img_read(&raw, infile)) {
216 ++frame_count;
217
218 if (frame_count == 22) {
219 set_roi_map(&cfg, &codec);
220 } else if (frame_count == 33) {
221 set_active_map(&cfg, &codec);
222 } else if (frame_count == 44) {
223 unset_active_map(&cfg, &codec);
177 } 224 }
178 225
179 /* Update the default configuration with our settings */ 226 encode_frame(&codec, &raw, frame_count, writer);
180 cfg.rc_target_bitrate = width * height * cfg.rc_target_bitrate 227 }
181 / cfg.g_w / cfg.g_h; 228 encode_frame(&codec, NULL, -1, writer);
182 cfg.g_w = width; 229 printf("\n");
183 cfg.g_h = height; 230 fclose(infile);
231 printf("Processed %d frames.\n", frame_count);
184 232
185 write_ivf_file_header(outfile, &cfg, 0); 233 vpx_img_free(&raw);
234 if (vpx_codec_destroy(&codec))
235 die_codec(&codec, "Failed to destroy codec.");
186 236
237 vpx_video_writer_close(writer);
187 238
188 /* Open input file for this encoding pass */ 239 return EXIT_SUCCESS;
189 if(!(infile = fopen(argv[3], "rb")))
190 die("Failed to open %s for reading", argv[3]);
191
192 /* Initialize codec */
193 if(vpx_codec_enc_init(&codec, interface, &cfg, 0))
194 die_codec(&codec, "Failed to initialize encoder");
195
196 frame_avail = 1;
197 got_data = 0;
198 while(frame_avail || got_data) {
199 vpx_codec_iter_t iter = NULL;
200 const vpx_codec_cx_pkt_t *pkt;
201
202 if(frame_cnt + 1 == 22) {
203 vpx_roi_map_t roi;
204 unsigned int i;
205
206 roi.rows = cfg.g_h/16;
207 roi.cols = cfg.g_w/16;
208
209 roi.delta_q[0] = 0;
210 roi.delta_q[1] = -2;
211 roi.delta_q[2] = -4;
212 roi.delta_q[3] = -6;
213
214 roi.delta_lf[0] = 0;
215 roi.delta_lf[1] = 1;
216 roi.delta_lf[2] = 2;
217 roi.delta_lf[3] = 3;
218
219 roi.static_threshold[0] = 1500;
220 roi.static_threshold[1] = 1000;
221 roi.static_threshold[2] = 500;
222 roi.static_threshold[3] = 0;
223
224 /* generate an ROI map for example */
225 roi.roi_map = malloc(roi.rows * roi.cols);
226 for(i=0;i<roi.rows*roi.cols;i++)
227 roi.roi_map[i] = i & 3;
228
229 if(vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
230 die_codec(&codec, "Failed to set ROI map");
231
232 free(roi.roi_map);
233 } else if(frame_cnt + 1 == 33) {
234 vpx_active_map_t active;
235 unsigned int i;
236
237 active.rows = cfg.g_h/16;
238 active.cols = cfg.g_w/16;
239
240 /* generate active map for example */
241 active.active_map = malloc(active.rows * active.cols);
242 for(i=0;i<active.rows*active.cols;i++)
243 active.active_map[i] = i & 1;
244
245 if(vpx_codec_control(&codec, VP8E_SET_ACTIVEMAP, &active))
246 die_codec(&codec, "Failed to set active map");
247
248 free(active.active_map);
249 } else if(frame_cnt + 1 == 44) {
250 vpx_active_map_t active;
251
252 active.rows = cfg.g_h/16;
253 active.cols = cfg.g_w/16;
254
255 /* pass in null map to disable active_map*/
256 active.active_map = NULL;
257
258 if(vpx_codec_control(&codec, VP8E_SET_ACTIVEMAP, &active))
259 die_codec(&codec, "Failed to set active map");
260 }
261 frame_avail = read_frame(infile, &raw);
262 if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt,
263 1, flags, VPX_DL_REALTIME))
264 die_codec(&codec, "Failed to encode frame");
265 got_data = 0;
266 while( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
267 got_data = 1;
268 switch(pkt->kind) {
269 case VPX_CODEC_CX_FRAME_PKT:
270 write_ivf_frame_header(outfile, pkt);
271 (void) fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
272 outfile);
273 break;
274 default:
275 break;
276 }
277 printf(pkt->kind == VPX_CODEC_CX_FRAME_PKT
278 && (pkt->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
279 fflush(stdout);
280 }
281 frame_cnt++;
282 }
283 printf("\n");
284 fclose(infile);
285
286 printf("Processed %d frames.\n",frame_cnt-1);
287 vpx_img_free(&raw);
288 if(vpx_codec_destroy(&codec))
289 die_codec(&codec, "Failed to destroy codec");
290
291 /* Try to rewrite the file header with the actual frame count */
292 if(!fseek(outfile, 0, SEEK_SET))
293 write_ivf_file_header(outfile, &cfg, frame_cnt-1);
294 fclose(outfile);
295 return EXIT_SUCCESS;
296 } 240 }
OLDNEW
« no previous file with comments | « source/libvpx/examples/vp8_multi_resolution_encoder.c ('k') | source/libvpx/examples/vp8cx_set_ref.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698