Index: source/libvpx/vpxdec.c |
=================================================================== |
--- source/libvpx/vpxdec.c (revision 292608) |
+++ source/libvpx/vpxdec.c (working copy) |
@@ -47,52 +47,49 @@ |
struct WebmInputContext *webm_ctx; |
}; |
-static const arg_def_t looparg = ARG_DEF(NULL, "loops", 1, |
- "Number of times to decode the file"); |
-static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1, |
- "Codec to use"); |
-static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0, |
- "Output raw YV12 frames"); |
-static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0, |
- "Output raw I420 frames"); |
-static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0, |
- "Flip the chroma planes in the output"); |
-static const arg_def_t rawvideo = ARG_DEF(NULL, "rawvideo", 0, |
- "Output raw YUV frames"); |
-static const arg_def_t noblitarg = ARG_DEF(NULL, "noblit", 0, |
- "Don't process the decoded frames"); |
-static const arg_def_t progressarg = ARG_DEF(NULL, "progress", 0, |
- "Show progress after each frame decodes"); |
-static const arg_def_t limitarg = ARG_DEF(NULL, "limit", 1, |
- "Stop decoding after n frames"); |
-static const arg_def_t skiparg = ARG_DEF(NULL, "skip", 1, |
- "Skip the first n input frames"); |
-static const arg_def_t postprocarg = ARG_DEF(NULL, "postproc", 0, |
- "Postprocess decoded frames"); |
-static const arg_def_t summaryarg = ARG_DEF(NULL, "summary", 0, |
- "Show timing summary"); |
-static const arg_def_t outputfile = ARG_DEF("o", "output", 1, |
- "Output file name pattern (see below)"); |
-static const arg_def_t threadsarg = ARG_DEF("t", "threads", 1, |
- "Max threads to use"); |
-static const arg_def_t verbosearg = ARG_DEF("v", "verbose", 0, |
- "Show version string"); |
-static const arg_def_t error_concealment = ARG_DEF(NULL, "error-concealment", 0, |
- "Enable decoder error-concealment"); |
-static const arg_def_t scalearg = ARG_DEF("S", "scale", 0, |
- "Scale output frames uniformly"); |
-static const arg_def_t continuearg = |
- ARG_DEF("k", "keep-going", 0, "(debug) Continue decoding after error"); |
- |
-static const arg_def_t fb_arg = |
- ARG_DEF(NULL, "frame-buffers", 1, "Number of frame buffers to use"); |
- |
-static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0, |
- "Compute the MD5 sum of the decoded frame"); |
+static const arg_def_t looparg = ARG_DEF( |
+ NULL, "loops", 1, "Number of times to decode the file"); |
+static const arg_def_t codecarg = ARG_DEF( |
+ NULL, "codec", 1, "Codec to use"); |
+static const arg_def_t use_yv12 = ARG_DEF( |
+ NULL, "yv12", 0, "Output raw YV12 frames"); |
+static const arg_def_t use_i420 = ARG_DEF( |
+ NULL, "i420", 0, "Output raw I420 frames"); |
+static const arg_def_t flipuvarg = ARG_DEF( |
+ NULL, "flipuv", 0, "Flip the chroma planes in the output"); |
+static const arg_def_t rawvideo = ARG_DEF( |
+ NULL, "rawvideo", 0, "Output raw YUV frames"); |
+static const arg_def_t noblitarg = ARG_DEF( |
+ NULL, "noblit", 0, "Don't process the decoded frames"); |
+static const arg_def_t progressarg = ARG_DEF( |
+ NULL, "progress", 0, "Show progress after each frame decodes"); |
+static const arg_def_t limitarg = ARG_DEF( |
+ NULL, "limit", 1, "Stop decoding after n frames"); |
+static const arg_def_t skiparg = ARG_DEF( |
+ NULL, "skip", 1, "Skip the first n input frames"); |
+static const arg_def_t postprocarg = ARG_DEF( |
+ NULL, "postproc", 0, "Postprocess decoded frames"); |
+static const arg_def_t summaryarg = ARG_DEF( |
+ NULL, "summary", 0, "Show timing summary"); |
+static const arg_def_t outputfile = ARG_DEF( |
+ "o", "output", 1, "Output file name pattern (see below)"); |
+static const arg_def_t threadsarg = ARG_DEF( |
+ "t", "threads", 1, "Max threads to use"); |
+static const arg_def_t verbosearg = ARG_DEF( |
+ "v", "verbose", 0, "Show version string"); |
+static const arg_def_t error_concealment = ARG_DEF( |
+ NULL, "error-concealment", 0, "Enable decoder error-concealment"); |
+static const arg_def_t scalearg = ARG_DEF( |
+ "S", "scale", 0, "Scale output frames uniformly"); |
+static const arg_def_t continuearg = ARG_DEF( |
+ "k", "keep-going", 0, "(debug) Continue decoding after error"); |
+static const arg_def_t fb_arg = ARG_DEF( |
+ NULL, "frame-buffers", 1, "Number of frame buffers to use"); |
+static const arg_def_t md5arg = ARG_DEF( |
+ NULL, "md5", 0, "Compute the MD5 sum of the decoded frame"); |
#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
static const arg_def_t outbitdeptharg = ARG_DEF( |
- NULL, "output-bit-depth", 1, |
- "Output bit-depth for decoded frames"); |
+ NULL, "output-bit-depth", 1, "Output bit-depth for decoded frames"); |
#endif |
static const arg_def_t *all_args[] = { |
@@ -527,175 +524,13 @@ |
} |
#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH |
-static void high_img_upshift(vpx_image_t *dst, vpx_image_t *src, |
- int input_shift) { |
- const int offset = input_shift > 0 ? (1 << (input_shift - 1)) : 0; |
- int plane; |
- if (dst->d_w != src->d_w || dst->d_h != src->d_h || |
- dst->x_chroma_shift != src->x_chroma_shift || |
- dst->y_chroma_shift != src->y_chroma_shift || |
- dst->fmt != src->fmt || input_shift < 0) { |
- fatal("Unsupported image conversion"); |
- } |
- switch (src->fmt) { |
- case VPX_IMG_FMT_I42016: |
- case VPX_IMG_FMT_I42216: |
- case VPX_IMG_FMT_I44416: |
- break; |
- default: |
- fatal("Unsupported image conversion"); |
- break; |
- } |
- for (plane = 0; plane < 3; plane++) { |
- int w = src->d_w; |
- int h = src->d_h; |
- int x, y; |
- if (plane) { |
- w >>= src->x_chroma_shift; |
- h >>= src->y_chroma_shift; |
- } |
- for (y = 0; y < h; y++) { |
- uint16_t *p_src = (uint16_t *)(src->planes[plane] + |
- y * src->stride[plane]); |
- uint16_t *p_dst = (uint16_t *)(dst->planes[plane] + |
- y * dst->stride[plane]); |
- for (x = 0; x < w; x++) |
- *p_dst++ = (*p_src++ << input_shift) + offset; |
- } |
- } |
+static int img_shifted_realloc_required(const vpx_image_t *img, |
+ const vpx_image_t *shifted, |
+ vpx_img_fmt_t required_fmt) { |
+ return img->d_w != shifted->d_w || |
+ img->d_h != shifted->d_h || |
+ required_fmt != shifted->fmt; |
} |
- |
-static void low_img_upshift(vpx_image_t *dst, vpx_image_t *src, |
- int input_shift) { |
- const int offset = input_shift > 0 ? (1 << (input_shift - 1)) : 0; |
- int plane; |
- if (dst->d_w != src->d_w || dst->d_h != src->d_h || |
- dst->x_chroma_shift != src->x_chroma_shift || |
- dst->y_chroma_shift != src->y_chroma_shift || |
- dst->fmt != src->fmt + VPX_IMG_FMT_HIGHBITDEPTH || |
- input_shift < 0) { |
- fatal("Unsupported image conversion"); |
- } |
- switch (src->fmt) { |
- case VPX_IMG_FMT_I420: |
- case VPX_IMG_FMT_I422: |
- case VPX_IMG_FMT_I444: |
- break; |
- default: |
- fatal("Unsupported image conversion"); |
- break; |
- } |
- for (plane = 0; plane < 3; plane++) { |
- int w = src->d_w; |
- int h = src->d_h; |
- int x, y; |
- if (plane) { |
- w >>= src->x_chroma_shift; |
- h >>= src->y_chroma_shift; |
- } |
- for (y = 0; y < h; y++) { |
- uint8_t *p_src = src->planes[plane] + y * src->stride[plane]; |
- uint16_t *p_dst = (uint16_t *)(dst->planes[plane] + |
- y * dst->stride[plane]); |
- for (x = 0; x < w; x++) { |
- *p_dst++ = (*p_src++ << input_shift) + offset; |
- } |
- } |
- } |
-} |
- |
-static void img_upshift(vpx_image_t *dst, vpx_image_t *src, |
- int input_shift) { |
- if (src->fmt & VPX_IMG_FMT_HIGHBITDEPTH) { |
- high_img_upshift(dst, src, input_shift); |
- } else { |
- low_img_upshift(dst, src, input_shift); |
- } |
-} |
- |
-static void high_img_downshift(vpx_image_t *dst, vpx_image_t *src, |
- int down_shift) { |
- int plane; |
- if (dst->d_w != src->d_w || dst->d_h != src->d_h || |
- dst->x_chroma_shift != src->x_chroma_shift || |
- dst->y_chroma_shift != src->y_chroma_shift || |
- dst->fmt != src->fmt || down_shift < 0) { |
- fatal("Unsupported image conversion"); |
- } |
- switch (src->fmt) { |
- case VPX_IMG_FMT_I42016: |
- case VPX_IMG_FMT_I42216: |
- case VPX_IMG_FMT_I44416: |
- break; |
- default: |
- fatal("Unsupported image conversion"); |
- break; |
- } |
- for (plane = 0; plane < 3; plane++) { |
- int w = src->d_w; |
- int h = src->d_h; |
- int x, y; |
- if (plane) { |
- w >>= src->x_chroma_shift; |
- h >>= src->y_chroma_shift; |
- } |
- for (y = 0; y < h; y++) { |
- uint16_t *p_src = (uint16_t *)(src->planes[plane] + |
- y * src->stride[plane]); |
- uint16_t *p_dst = (uint16_t *)(dst->planes[plane] + |
- y * dst->stride[plane]); |
- for (x = 0; x < w; x++) |
- *p_dst++ = *p_src++ >> down_shift; |
- } |
- } |
-} |
- |
-static void low_img_downshift(vpx_image_t *dst, vpx_image_t *src, |
- int down_shift) { |
- int plane; |
- if (dst->d_w != src->d_w || dst->d_h != src->d_h || |
- dst->x_chroma_shift != src->x_chroma_shift || |
- dst->y_chroma_shift != src->y_chroma_shift || |
- src->fmt != dst->fmt + VPX_IMG_FMT_HIGHBITDEPTH || |
- down_shift < 0) { |
- fatal("Unsupported image conversion"); |
- } |
- switch (dst->fmt) { |
- case VPX_IMG_FMT_I420: |
- case VPX_IMG_FMT_I422: |
- case VPX_IMG_FMT_I444: |
- break; |
- default: |
- fatal("Unsupported image conversion"); |
- break; |
- } |
- for (plane = 0; plane < 3; plane++) { |
- int w = src->d_w; |
- int h = src->d_h; |
- int x, y; |
- if (plane) { |
- w >>= src->x_chroma_shift; |
- h >>= src->y_chroma_shift; |
- } |
- for (y = 0; y < h; y++) { |
- uint16_t *p_src = (uint16_t *)(src->planes[plane] + |
- y * src->stride[plane]); |
- uint8_t *p_dst = dst->planes[plane] + y * dst->stride[plane]; |
- for (x = 0; x < w; x++) { |
- *p_dst++ = *p_src++ >> down_shift; |
- } |
- } |
- } |
-} |
- |
-static void img_downshift(vpx_image_t *dst, vpx_image_t *src, |
- int down_shift) { |
- if (dst->fmt & VPX_IMG_FMT_HIGHBITDEPTH) { |
- high_img_downshift(dst, src, down_shift); |
- } else { |
- low_img_downshift(dst, src, down_shift); |
- } |
-} |
#endif |
int main_loop(int argc, const char **argv_) { |
@@ -933,7 +768,7 @@ |
if (use_y4m && !noblit) { |
if (!single_file) { |
fprintf(stderr, "YUV4MPEG2 not supported with output patterns," |
- " try --i420 or --yv12.\n"); |
+ " try --i420 or --yv12 or --rawvideo.\n"); |
return EXIT_FAILURE; |
} |
@@ -1130,22 +965,25 @@ |
} |
// Shift up or down if necessary |
if (output_bit_depth != img->bit_depth) { |
+ const vpx_img_fmt_t shifted_fmt = output_bit_depth == 8 ? |
+ img->fmt ^ (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) : |
+ img->fmt | VPX_IMG_FMT_HIGHBITDEPTH; |
+ if (img_shifted && |
+ img_shifted_realloc_required(img, img_shifted, shifted_fmt)) { |
+ vpx_img_free(img_shifted); |
+ img_shifted = NULL; |
+ } |
if (!img_shifted) { |
- if (output_bit_depth == 8) { |
- img_shifted = vpx_img_alloc( |
- NULL, img->fmt - VPX_IMG_FMT_HIGHBITDEPTH, |
- img->d_w, img->d_h, 16); |
- } else { |
- img_shifted = vpx_img_alloc( |
- NULL, img->fmt | VPX_IMG_FMT_HIGHBITDEPTH, |
- img->d_w, img->d_h, 16); |
- } |
+ img_shifted = vpx_img_alloc(NULL, shifted_fmt, |
+ img->d_w, img->d_h, 16); |
img_shifted->bit_depth = output_bit_depth; |
} |
if (output_bit_depth > img->bit_depth) { |
- img_upshift(img_shifted, img, output_bit_depth - img->bit_depth); |
+ vpx_img_upshift(img_shifted, img, |
+ output_bit_depth - img->bit_depth); |
} else { |
- img_downshift(img_shifted, img, img->bit_depth - output_bit_depth); |
+ vpx_img_downshift(img_shifted, img, |
+ img->bit_depth - output_bit_depth); |
} |
img = img_shifted; |
} |
@@ -1155,6 +993,10 @@ |
if (use_y4m) { |
char buf[Y4M_BUFFER_SIZE] = {0}; |
size_t len = 0; |
+ if (img->fmt == VPX_IMG_FMT_I440 || img->fmt == VPX_IMG_FMT_I44016) { |
+ fprintf(stderr, "Cannot produce y4m output for 440 sampling.\n"); |
+ goto fail; |
+ } |
if (frame_out == 1) { |
// Y4M file header |
len = y4m_write_file_header(buf, sizeof(buf), |