annotate libvpxenc.c @ 12092:de9e45d04063 libavcodec

DCA: Occasionally a false XCH sync word can turn up after the core DTS data, to verify the sync word the extension fsize field should be compared to the core data length field. Patch by nick.nbrereton@net
author banan
date Mon, 05 Jul 2010 08:16:43 +0000
parents 24a6c651c3f3
children 3d186eff2224
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11821
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
1 /*
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
2 * Copyright (c) 2010, Google, Inc.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
3 *
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
4 * This file is part of FFmpeg.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
5 *
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
6 * FFmpeg is free software; you can redistribute it and/or
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
9 * version 2.1 of the License, or (at your option) any later version.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
10 *
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
11 * FFmpeg is distributed in the hope that it will be useful,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
14 * Lesser General Public License for more details.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
15 *
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
17 * License along with FFmpeg; if not, write to the Free Software
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
19 */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
20
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
21 /**
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
22 * @file
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
23 * VP8 encoder support via libvpx
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
24 */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
25
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
26 #define VPX_DISABLE_CTRL_TYPECHECKS 1
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
27 #define VPX_CODEC_DISABLE_COMPAT 1
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
28 #include <vpx/vpx_encoder.h>
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
29 #include <vpx/vp8cx.h>
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
30
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
31 #include "avcodec.h"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
32 #include "libavutil/base64.h"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
33
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
34 /**
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
35 * Portion of struct vpx_codec_cx_pkt from vpx_encoder.h.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
36 * One encoded frame returned from the library.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
37 */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
38 struct FrameListData {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
39 void *buf; /**≤ compressed data buffer */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
40 size_t sz; /**≤ length of compressed data */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
41 int64_t pts; /**≤ time stamp to show frame
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
42 (in timebase units) */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
43 unsigned long duration; /**≤ duration to show frame
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
44 (in timebase units) */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
45 uint32_t flags; /**≤ flags for this frame */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
46 struct FrameListData *next;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
47 };
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
48
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
49 typedef struct VP8EncoderContext {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
50 struct vpx_codec_ctx encoder;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
51 struct vpx_image rawimg;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
52 struct vpx_fixed_buf twopass_stats;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
53 unsigned long deadline; //i.e., RT/GOOD/BEST
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
54 struct FrameListData *coded_frame_list;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
55 } VP8Context;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
56
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
57 /** String mappings for enum vp8e_enc_control_id */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
58 static const char *ctlidstr[] = {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
59 [VP8E_UPD_ENTROPY] = "VP8E_UPD_ENTROPY",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
60 [VP8E_UPD_REFERENCE] = "VP8E_UPD_REFERENCE",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
61 [VP8E_USE_REFERENCE] = "VP8E_USE_REFERENCE",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
62 [VP8E_SET_ROI_MAP] = "VP8E_SET_ROI_MAP",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
63 [VP8E_SET_ACTIVEMAP] = "VP8E_SET_ACTIVEMAP",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
64 [VP8E_SET_SCALEMODE] = "VP8E_SET_SCALEMODE",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
65 [VP8E_SET_CPUUSED] = "VP8E_SET_CPUUSED",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
66 [VP8E_SET_ENABLEAUTOALTREF] = "VP8E_SET_ENABLEAUTOALTREF",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
67 [VP8E_SET_NOISE_SENSITIVITY] = "VP8E_SET_NOISE_SENSITIVITY",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
68 [VP8E_SET_SHARPNESS] = "VP8E_SET_SHARPNESS",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
69 [VP8E_SET_STATIC_THRESHOLD] = "VP8E_SET_STATIC_THRESHOLD",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
70 [VP8E_SET_TOKEN_PARTITIONS] = "VP8E_SET_TOKEN_PARTITIONS",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
71 [VP8E_GET_LAST_QUANTIZER] = "VP8E_GET_LAST_QUANTIZER",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
72 [VP8E_SET_ARNR_MAXFRAMES] = "VP8E_SET_ARNR_MAXFRAMES",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
73 [VP8E_SET_ARNR_STRENGTH] = "VP8E_SET_ARNR_STRENGTH",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
74 [VP8E_SET_ARNR_TYPE] = "VP8E_SET_ARNR_TYPE",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
75 };
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
76
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
77 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
78 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
79 VP8Context *ctx = avctx->priv_data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
80 const char *error = vpx_codec_error(&ctx->encoder);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
81 const char *detail = vpx_codec_error_detail(&ctx->encoder);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
82
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
83 av_log(avctx, AV_LOG_ERROR, "%s: %s\n", desc, error);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
84 if (detail)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
85 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", detail);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
86 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
87
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
88 static av_cold void dump_enc_cfg(AVCodecContext *avctx,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
89 const struct vpx_codec_enc_cfg *cfg)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
90 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
91 int width = -30;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
92 int level = AV_LOG_DEBUG;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
93
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
94 av_log(avctx, level, "vpx_codec_enc_cfg\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
95 av_log(avctx, level, "generic settings\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
96 " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
97 " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
98 width, "g_usage:", cfg->g_usage,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
99 width, "g_threads:", cfg->g_threads,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
100 width, "g_profile:", cfg->g_profile,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
101 width, "g_w:", cfg->g_w,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
102 width, "g_h:", cfg->g_h,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
103 width, "g_timebase:", cfg->g_timebase.num, cfg->g_timebase.den,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
104 width, "g_error_resilient:", cfg->g_error_resilient,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
105 width, "g_pass:", cfg->g_pass,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
106 width, "g_lag_in_frames:", cfg->g_lag_in_frames);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
107 av_log(avctx, level, "rate control settings\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
108 " %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
109 " %*s%d\n %*s%p(%zu)\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
110 width, "rc_dropframe_thresh:", cfg->rc_dropframe_thresh,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
111 width, "rc_resize_allowed:", cfg->rc_resize_allowed,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
112 width, "rc_resize_up_thresh:", cfg->rc_resize_up_thresh,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
113 width, "rc_resize_down_thresh:", cfg->rc_resize_down_thresh,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
114 width, "rc_end_usage:", cfg->rc_end_usage,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
115 width, "rc_twopass_stats_in:", cfg->rc_twopass_stats_in.buf, cfg->rc_twopass_stats_in.sz,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
116 width, "rc_target_bitrate:", cfg->rc_target_bitrate);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
117 av_log(avctx, level, "quantizer settings\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
118 " %*s%u\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
119 width, "rc_min_quantizer:", cfg->rc_min_quantizer,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
120 width, "rc_max_quantizer:", cfg->rc_max_quantizer);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
121 av_log(avctx, level, "bitrate tolerance\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
122 " %*s%u\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
123 width, "rc_undershoot_pct:", cfg->rc_undershoot_pct,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
124 width, "rc_overshoot_pct:", cfg->rc_overshoot_pct);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
125 av_log(avctx, level, "decoder buffer model\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
126 " %*s%u\n %*s%u\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
127 width, "rc_buf_sz:", cfg->rc_buf_sz,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
128 width, "rc_buf_initial_sz:", cfg->rc_buf_initial_sz,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
129 width, "rc_buf_optimal_sz:", cfg->rc_buf_optimal_sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
130 av_log(avctx, level, "2 pass rate control settings\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
131 " %*s%u\n %*s%u\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
132 width, "rc_2pass_vbr_bias_pct:", cfg->rc_2pass_vbr_bias_pct,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
133 width, "rc_2pass_vbr_minsection_pct:", cfg->rc_2pass_vbr_minsection_pct,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
134 width, "rc_2pass_vbr_maxsection_pct:", cfg->rc_2pass_vbr_maxsection_pct);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
135 av_log(avctx, level, "keyframing settings\n"
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
136 " %*s%d\n %*s%u\n %*s%u\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
137 width, "kf_mode:", cfg->kf_mode,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
138 width, "kf_min_dist:", cfg->kf_min_dist,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
139 width, "kf_max_dist:", cfg->kf_max_dist);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
140 av_log(avctx, level, "\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
141 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
142
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
143 static void coded_frame_add(void *list, struct FrameListData *cx_frame)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
144 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
145 struct FrameListData **p = list;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
146
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
147 while (*p != NULL)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
148 p = &(*p)->next;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
149 *p = cx_frame;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
150 cx_frame->next = NULL;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
151 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
152
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
153 static av_cold void free_coded_frame(struct FrameListData *cx_frame)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
154 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
155 av_freep(&cx_frame->buf);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
156 av_freep(&cx_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
157 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
158
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
159 static av_cold void free_frame_list(struct FrameListData *list)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
160 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
161 struct FrameListData *p = list;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
162
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
163 while (p) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
164 list = list->next;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
165 free_coded_frame(p);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
166 p = list;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
167 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
168 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
169
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
170 static av_cold int codecctl_int(AVCodecContext *avctx,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
171 enum vp8e_enc_control_id id, int val)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
172 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
173 VP8Context *ctx = avctx->priv_data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
174 char buf[80];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
175 int width = -30;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
176 int res;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
177
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
178 snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
179 av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, val);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
180
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
181 res = vpx_codec_control(&ctx->encoder, id, val);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
182 if (res != VPX_CODEC_OK) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
183 snprintf(buf, sizeof(buf), "Failed to set %s codec control",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
184 ctlidstr[id]);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
185 log_encoder_error(avctx, buf);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
186 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
187
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
188 return res == VPX_CODEC_OK ? 0 : AVERROR(EINVAL);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
189 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
190
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
191 static av_cold int vp8_free(AVCodecContext *avctx)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
192 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
193 VP8Context *ctx = avctx->priv_data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
194
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
195 vpx_codec_destroy(&ctx->encoder);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
196 av_freep(&ctx->twopass_stats.buf);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
197 av_freep(&avctx->coded_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
198 av_freep(&avctx->stats_out);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
199 free_frame_list(ctx->coded_frame_list);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
200 return 0;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
201 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
202
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
203 static av_cold int vp8_init(AVCodecContext *avctx)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
204 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
205 VP8Context *ctx = avctx->priv_data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
206 const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
207 int cpuused = 3;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
208 struct vpx_codec_enc_cfg enccfg;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
209 int res;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
210
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
211 av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
212 av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
213
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
214 if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
215 av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
216 vpx_codec_err_to_string(res));
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
217 return AVERROR(EINVAL);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
218 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
219 dump_enc_cfg(avctx, &enccfg);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
220
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
221 enccfg.g_w = avctx->width;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
222 enccfg.g_h = avctx->height;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
223 enccfg.g_timebase.num = avctx->time_base.num;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
224 enccfg.g_timebase.den = avctx->time_base.den;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
225 enccfg.g_threads = avctx->thread_count;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
226
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
227 if (avctx->flags & CODEC_FLAG_PASS1)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
228 enccfg.g_pass = VPX_RC_FIRST_PASS;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
229 else if (avctx->flags & CODEC_FLAG_PASS2)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
230 enccfg.g_pass = VPX_RC_LAST_PASS;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
231 else
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
232 enccfg.g_pass = VPX_RC_ONE_PASS;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
233
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
234 if (avctx->rc_min_rate == avctx->rc_max_rate &&
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
235 avctx->rc_min_rate == avctx->bit_rate)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
236 enccfg.rc_end_usage = VPX_CBR;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
237 enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
238 AV_ROUND_NEAR_INF);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
239
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
240 //convert [1,51] -> [0,63]
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
241 enccfg.rc_min_quantizer = ((avctx->qmin * 5 + 1) >> 2) - 1;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
242 enccfg.rc_max_quantizer = ((avctx->qmax * 5 + 1) >> 2) - 1;
11852
24a6c651c3f3 libvpx: Set the libvpx frame dropping threshold to frame_skip_threshold
mstorsjo
parents: 11851
diff changeset
243 enccfg.rc_dropframe_thresh = avctx->frame_skip_threshold;
11821
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
244
11851
3e97c4c25ec3 libvpx: Don't use the VPX_KF_FIXED mode
mstorsjo
parents: 11846
diff changeset
245 //_enc_init() will balk if kf_min_dist differs from max w/VPX_KF_AUTO
11821
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
246 if (avctx->keyint_min == avctx->gop_size)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
247 enccfg.kf_min_dist = avctx->keyint_min;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
248 enccfg.kf_max_dist = avctx->gop_size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
249
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
250 if (enccfg.g_pass == VPX_RC_FIRST_PASS)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
251 enccfg.g_lag_in_frames = 0;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
252 else if (enccfg.g_pass == VPX_RC_LAST_PASS) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
253 int decode_size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
254
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
255 if (!avctx->stats_in) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
256 av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
257 return AVERROR_INVALIDDATA;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
258 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
259
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
260 ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
261 ctx->twopass_stats.buf = av_malloc(ctx->twopass_stats.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
262 if (!ctx->twopass_stats.buf) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
263 av_log(avctx, AV_LOG_ERROR,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
264 "Stat buffer alloc (%zu bytes) failed\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
265 ctx->twopass_stats.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
266 return AVERROR(ENOMEM);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
267 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
268 decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
269 ctx->twopass_stats.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
270 if (decode_size < 0) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
271 av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
272 return AVERROR_INVALIDDATA;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
273 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
274
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
275 ctx->twopass_stats.sz = decode_size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
276 enccfg.rc_twopass_stats_in = ctx->twopass_stats;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
277 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
278
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
279 ctx->deadline = VPX_DL_GOOD_QUALITY;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
280
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
281 dump_enc_cfg(avctx, &enccfg);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
282 /* Construct Encoder Context */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
283 res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, 0);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
284 if (res != VPX_CODEC_OK) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
285 log_encoder_error(avctx, "Failed to initialize encoder");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
286 return AVERROR(EINVAL);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
287 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
288
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
289 //codec control failures are currently treated only as warnings
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
290 av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
291 codecctl_int(avctx, VP8E_SET_CPUUSED, cpuused);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
292 codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
293
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
294 //provide dummy value to initialize wrapper, values will be updated each _encode()
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
295 vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
296 (unsigned char*)1);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
297
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
298 avctx->coded_frame = avcodec_alloc_frame();
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
299 if (!avctx->coded_frame) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
300 av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
301 vp8_free(avctx);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
302 return AVERROR(ENOMEM);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
303 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
304 return 0;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
305 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
306
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
307 static inline void cx_pktcpy(struct FrameListData *dst,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
308 const struct vpx_codec_cx_pkt *src)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
309 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
310 dst->pts = src->data.frame.pts;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
311 dst->duration = src->data.frame.duration;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
312 dst->flags = src->data.frame.flags;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
313 dst->sz = src->data.frame.sz;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
314 dst->buf = src->data.frame.buf;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
315 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
316
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
317 /**
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
318 * Store coded frame information in format suitable for return from encode().
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
319 *
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
320 * Write buffer information from @a cx_frame to @a buf & @a buf_size.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
321 * Timing/frame details to @a coded_frame.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
322 * @return Frame size written to @a buf on success
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
323 * @return AVERROR(EINVAL) on error
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
324 */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
325 static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
326 uint8_t *buf, int buf_size, AVFrame *coded_frame)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
327 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
328 if ((int) cx_frame->sz <= buf_size) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
329 buf_size = cx_frame->sz;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
330 memcpy(buf, cx_frame->buf, buf_size);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
331 coded_frame->pts = cx_frame->pts;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
332 coded_frame->key_frame = !!(cx_frame->flags & VPX_FRAME_IS_KEY);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
333
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
334 if (coded_frame->key_frame)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
335 coded_frame->pict_type = FF_I_TYPE;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
336 else
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
337 coded_frame->pict_type = FF_P_TYPE;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
338 } else {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
339 av_log(avctx, AV_LOG_ERROR,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
340 "Compressed frame larger than storage provided! (%zu/%d)\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
341 cx_frame->sz, buf_size);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
342 return AVERROR(EINVAL);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
343 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
344 return buf_size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
345 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
346
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
347 /**
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
348 * Queue multiple output frames from the encoder, returning the front-most.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
349 * In cases where vpx_codec_get_cx_data() returns more than 1 frame append
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
350 * the frame queue. Return the head frame if available.
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
351 * @return Stored frame size
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
352 * @return AVERROR(EINVAL) on output size error
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
353 * @return AVERROR(ENOMEM) on coded frame queue data allocation error
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
354 */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
355 static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
356 AVFrame *coded_frame)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
357 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
358 VP8Context *ctx = avctx->priv_data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
359 const struct vpx_codec_cx_pkt *pkt;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
360 const void *iter = NULL;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
361 int size = 0;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
362
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
363 if (ctx->coded_frame_list) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
364 struct FrameListData *cx_frame = ctx->coded_frame_list;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
365 /* return the leading frame if we've already begun queueing */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
366 size = storeframe(avctx, cx_frame, buf, buf_size, coded_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
367 if (size < 0)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
368 return AVERROR(EINVAL);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
369 ctx->coded_frame_list = cx_frame->next;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
370 free_coded_frame(cx_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
371 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
372
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
373 /* consume all available output from the encoder before returning. buffers
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
374 are only good through the next vpx_codec call */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
375 while ((pkt = vpx_codec_get_cx_data(&ctx->encoder, &iter))) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
376 switch (pkt->kind) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
377 case VPX_CODEC_CX_FRAME_PKT:
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
378 if (!size) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
379 struct FrameListData cx_frame;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
380
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
381 /* avoid storing the frame when the list is empty and we haven't yet
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
382 provided a frame for output */
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
383 assert(!ctx->coded_frame_list);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
384 cx_pktcpy(&cx_frame, pkt);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
385 size = storeframe(avctx, &cx_frame, buf, buf_size, coded_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
386 if (size < 0)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
387 return AVERROR(EINVAL);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
388 } else {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
389 struct FrameListData *cx_frame =
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
390 av_malloc(sizeof(struct FrameListData));
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
391
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
392 if (!cx_frame) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
393 av_log(avctx, AV_LOG_ERROR,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
394 "Frame queue element alloc failed\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
395 return AVERROR(ENOMEM);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
396 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
397 cx_pktcpy(cx_frame, pkt);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
398 cx_frame->buf = av_malloc(cx_frame->sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
399
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
400 if (!cx_frame->buf) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
401 av_log(avctx, AV_LOG_ERROR,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
402 "Data buffer alloc (%zu bytes) failed\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
403 cx_frame->sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
404 return AVERROR(ENOMEM);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
405 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
406 memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
407 coded_frame_add(&ctx->coded_frame_list, cx_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
408 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
409 break;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
410 case VPX_CODEC_STATS_PKT: {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
411 struct vpx_fixed_buf *stats = &ctx->twopass_stats;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
412 stats->buf = av_realloc(stats->buf,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
413 stats->sz + pkt->data.twopass_stats.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
414 if (!stats->buf) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
415 av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
416 return AVERROR(ENOMEM);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
417 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
418 memcpy((uint8_t*)stats->buf + stats->sz,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
419 pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
420 stats->sz += pkt->data.twopass_stats.sz;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
421 break;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
422 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
423 case VPX_CODEC_PSNR_PKT: //FIXME add support for CODEC_FLAG_PSNR
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
424 case VPX_CODEC_CUSTOM_PKT:
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
425 //ignore unsupported/unrecognized packet types
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
426 break;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
427 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
428 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
429
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
430 return size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
431 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
432
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
433 static int vp8_encode(AVCodecContext *avctx, uint8_t *buf, int buf_size,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
434 void *data)
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
435 {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
436 VP8Context *ctx = avctx->priv_data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
437 AVFrame *frame = data;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
438 struct vpx_image *rawimg = NULL;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
439 int64_t timestamp = 0;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
440 int res, coded_size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
441
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
442 if (frame) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
443 rawimg = &ctx->rawimg;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
444 rawimg->planes[VPX_PLANE_Y] = frame->data[0];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
445 rawimg->planes[VPX_PLANE_U] = frame->data[1];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
446 rawimg->planes[VPX_PLANE_V] = frame->data[2];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
447 rawimg->stride[VPX_PLANE_Y] = frame->linesize[0];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
448 rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
449 rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
450 timestamp = frame->pts;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
451 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
452
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
453 res = vpx_codec_encode(&ctx->encoder, rawimg, timestamp,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
454 avctx->ticks_per_frame, 0, ctx->deadline);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
455 if (res != VPX_CODEC_OK) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
456 log_encoder_error(avctx, "Error encoding frame");
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
457 return AVERROR_INVALIDDATA;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
458 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
459 coded_size = queue_frames(avctx, buf, buf_size, avctx->coded_frame);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
460
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
461 if (!frame && avctx->flags & CODEC_FLAG_PASS1) {
11846
44a08df9971c Use new macro AV_BASE64_SIZE.
cehoyos
parents: 11821
diff changeset
462 unsigned int b64_size = AV_BASE64_SIZE(ctx->twopass_stats.sz);
11821
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
463
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
464 avctx->stats_out = av_malloc(b64_size);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
465 if (!avctx->stats_out) {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
466 av_log(avctx, AV_LOG_ERROR, "Stat buffer alloc (%d bytes) failed\n",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
467 b64_size);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
468 return AVERROR(ENOMEM);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
469 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
470 av_base64_encode(avctx->stats_out, b64_size, ctx->twopass_stats.buf,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
471 ctx->twopass_stats.sz);
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
472 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
473 return coded_size;
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
474 }
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
475
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
476 AVCodec libvpx_encoder = {
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
477 "libvpx",
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
478 AVMEDIA_TYPE_VIDEO,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
479 CODEC_ID_VP8,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
480 sizeof(VP8Context),
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
481 vp8_init,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
482 vp8_encode,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
483 vp8_free,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
484 NULL,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
485 CODEC_CAP_DELAY,
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
486 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
487 .long_name = NULL_IF_CONFIG_SMALL("libvpx VP8"),
9f7414707aa8 VP8 encoding via libvpx.
cehoyos
parents:
diff changeset
488 };