| 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),
|
|
|