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