nsresult
SoftwareWebMVideoDecoder::Init(unsigned int aWidth, unsigned int aHeight)
{
  int decode_threads = 2; //Default to 2 threads for small sizes or VP8
   
  vpx_codec_iface_t* dx = nullptr;
  switch(mReader->GetVideoCodec()) {
    case NESTEGG_CODEC_VP8:
      dx = vpx_codec_vp8_dx();
      break;
    case NESTEGG_CODEC_VP9:
      dx = vpx_codec_vp9_dx();
      if (aWidth >= 2048) {
        decode_threads = 8;
      } else if (aWidth >= 1024) {
        decode_threads = 4;
      }      
      break;
  }
  
  // Never exceed the number of system cores!
  decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors());

  vpx_codec_dec_cfg_t config;
  config.threads = decode_threads;
  config.w = aWidth;
  config.h = aHeight;

  if (!dx || vpx_codec_dec_init(&mVPX, dx, &config, 0)) {
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}
Exemplo n.º 2
0
/**
    \fn ctor
*/
decoderVPX::decoderVPX (uint32_t w, uint32_t h,uint32_t fcc, uint32_t extraDataLen, uint8_t *extraData,uint32_t bpp)
        : decoders(  w,   h,  fcc,   extraDataLen,  extraData,  bpp)
{   
    alive=false;
    vpx=NULL;
    vpx_codec_dec_cfg_t cfg;
    vpx_codec_flags_t flags=0; //VPX_CODEC_USE_POSTPROC
    vpx_codec_ctx_t *instance=new vpx_codec_ctx_t;
    const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo;
    
    memset(instance,0,sizeof(*instance));
    memset(&cfg,0,sizeof(cfg));
    cfg.threads=1;
    cfg.w=w;
    cfg.h=h;
    if(VPX_CODEC_OK!=vpx_codec_dec_init(instance, iface, &cfg, flags))
    {
        delete instance;
        ADM_warning("Vpx init ko\n");
    }else
    {
        alive=true;
        vpx=(void *)instance;
        ADM_info("Vpx init ok\n");

    }
}
Exemplo n.º 3
0
int
x_vpx_decoder_init(vpx_codec_ctx_t *_decoder, int numcores)
{
  vpx_codec_dec_cfg_t cfg;
  vpx_codec_flags_t flags = 0;
  int err;

  cfg.threads = 1;
  cfg.h = cfg.w = 0; // set after decode

#if WEBRTC_LIBVPX_VERSION >= 971
  flags = VPX_CODEC_USE_ERROR_CONCEALMENT | VPX_CODEC_USE_POSTPROC;
#ifdef INDEPENDENT_PARTITIONS
  flags |= VPX_CODEC_USE_INPUT_PARTITION;
#endif
#endif

  if (vpx_codec_dec_init(_decoder, vpx_codec_vp8_dx(), &cfg, flags))
    {
      return -ENOMEM;
    }

#if WEBRTC_LIBVPX_VERSION >= 971
  vp8_postproc_cfg_t ppcfg;
  // Disable deblocking for now due to uninitialized memory being returned.
  ppcfg.post_proc_flag = 0;
  // Strength of deblocking filter. Valid range:[0,16]
  //ppcfg.deblocking_level = 3;
  vpx_codec_control(_decoder, VP8_SET_POSTPROC, &ppcfg);
#endif

  return 0;
}
Exemplo n.º 4
0
OMX_ERRORTYPE OMXVideoDecoderVP9HWR::initDecoder()
{
    mCtx = new vpx_codec_ctx_t;
    vpx_codec_err_t vpx_err;
    vpx_codec_dec_cfg_t cfg;
    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
    cfg.threads = GetCPUCoreCount();
    if ((vpx_err = vpx_codec_dec_init(
                (vpx_codec_ctx_t *)mCtx,
                 &vpx_codec_vp9_dx_algo,
                 &cfg, 0))) {
        LOGE("on2 decoder failed to initialize. (%d)", vpx_err);
        return OMX_ErrorNotReady;
    }

    mNumFrameBuffer = OUTPORT_NATIVE_BUFFER_COUNT;

    if (vpx_codec_set_frame_buffer_functions((vpx_codec_ctx_t *)mCtx,
                                    getVP9FrameBuffer,
                                    releaseVP9FrameBuffer,
                                    this)) {
      LOGE("Failed to configure external frame buffers");
      return OMX_ErrorNotReady;
    }

    return OMX_ErrorNone;
}
Exemplo n.º 5
0
HRESULT Inpin::Start()
{
    m_bEndOfStream = false;
    m_bFlush = false;

    vpx_codec_iface_t& vp8 = vpx_codec_vp8_dx_algo;

    const int flags = VPX_CODEC_USE_POSTPROC;

    const vpx_codec_err_t err = vpx_codec_dec_init(
                                    &m_ctx,
                                    &vp8,
                                    0,
                                    flags);

    if (err == VPX_CODEC_MEM_ERROR)
        return E_OUTOFMEMORY;

    if (err != VPX_CODEC_OK)
        return E_FAIL;

    const HRESULT hr = OnApplyPostProcessing();

    if (FAILED(hr))
    {
        Stop();
        return hr;
    }

    return S_OK;
}
Exemplo n.º 6
0
krad_vpx_decoder_t *krad_vpx_decoder_create () {

  krad_vpx_decoder_t *vpx;
  
  vpx = calloc (1, sizeof(krad_vpx_decoder_t));

  vpx->stream_info.sz = sizeof (vpx->stream_info);
  vpx->dec_flags = 0;
  vpx->cfg.threads = 3;
  
  vpx_codec_dec_init (&vpx->decoder,
                     vpx_codec_vp8_dx(),
                     &vpx->cfg,
                     vpx->dec_flags);

  //vpx->ppcfg.post_proc_flag = VP8_DEBLOCK;
  //vpx->ppcfg.deblocking_level = 1;
  //vpx->ppcfg.noise_level = 0;

  vpx->ppcfg.post_proc_flag = VP8_DEMACROBLOCK | VP8_DEBLOCK | VP8_ADDNOISE;
  vpx->ppcfg.deblocking_level = 5;
  vpx->ppcfg.noise_level = 1;

  vpx_codec_control (&vpx->decoder, VP8_SET_POSTPROC, &vpx->ppcfg);

  vpx->img = NULL;

  return vpx;
}
Exemplo n.º 7
0
static void dec_preprocess(MSFilter* f) {
	DecState *s = (DecState *)f->data;
	vpx_codec_caps_t caps = vpx_codec_get_caps(s->iface);

	/* Initialize codec */
	if (!s->ready){
		s->flags = 0;
		if ((s->avpf_enabled == TRUE) && (caps & VPX_CODEC_CAP_INPUT_FRAGMENTS)) {
			s->flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
		}
		if (caps & VPX_CODEC_CAP_ERROR_CONCEALMENT) {
			s->flags |= VPX_CODEC_USE_ERROR_CONCEALMENT;
		}
	#ifdef VPX_CODEC_CAP_FRAME_THREADING
		if ((caps & VPX_CODEC_CAP_FRAME_THREADING) && (ms_factory_get_cpu_count(f->factory) > 1)) {
			s->flags |= VPX_CODEC_USE_FRAME_THREADING;
		}
	#endif
		if(vpx_codec_dec_init(&s->codec, s->iface, NULL, s->flags))
			ms_error("Failed to initialize decoder");
		ms_message("VP8: initializing decoder context: avpf=[%i] freeze_on_error=[%i]",s->avpf_enabled,s->freeze_on_error);
		vp8rtpfmt_unpacker_init(&s->unpacker, f, s->avpf_enabled, s->freeze_on_error, (s->flags & VPX_CODEC_USE_INPUT_FRAGMENTS) ? TRUE : FALSE);
		s->first_image_decoded = FALSE;
		s->ready=TRUE;
	}

}
Exemplo n.º 8
0
int main(int argc, char **argv) {
  int frame_cnt = 0;
  FILE *outfile = NULL;
  vpx_codec_ctx_t codec;
  VpxVideoReader *reader = NULL;
  const VpxInterface *decoder = NULL;
  const VpxVideoInfo *info = NULL;

  exec_name = argv[0];

  if (argc != 3)
    die("Invalid number of arguments.");

  reader = vpx_video_reader_open(argv[1]);
  if (!reader)
    die("Failed to open %s for reading.", argv[1]);

  if (!(outfile = fopen(argv[2], "wb")))
    die("Failed to open %s for writing.", argv[2]);

  info = vpx_video_reader_get_info(reader);

  decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
  if (!decoder)
    die("Unknown input codec.");

  printf("Using %s\n", vpx_codec_iface_name(decoder->interface()));

  if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0))
    die_codec(&codec, "Failed to initialize decoder.");

  while (vpx_video_reader_read_frame(reader)) {
    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img = NULL;
    size_t frame_size = 0;
    const unsigned char *frame = vpx_video_reader_get_frame(reader,
                                                            &frame_size);
    if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
      die_codec(&codec, "Failed to decode frame.");

    while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) {
      vpx_img_write(img, outfile);
      ++frame_cnt;
    }
  }

  printf("Processed %d frames.\n", frame_cnt);
  if (vpx_codec_destroy(&codec))
    die_codec(&codec, "Failed to destroy codec");

  printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
         info->frame_width, info->frame_height, argv[2]);

  vpx_video_reader_close(reader);

  fclose(outfile);

  return EXIT_SUCCESS;
}
Exemplo n.º 9
0
int main(int argc, char **argv) {
  int frame_cnt = 0;
  FILE *outfile = NULL;
  vpx_codec_ctx_t codec;
  VpxVideoReader *reader = NULL;
  const VpxVideoInfo *info = NULL;
  const VpxInterface *decoder = NULL;

  exec_name = argv[0];

  if (argc != 3)
    die("Invalid number of arguments.");

  reader = vpx_video_reader_open(argv[1]);
  if (!reader)
    die("Failed to open %s for reading.", argv[1]);

  if (!(outfile = fopen(argv[2], "wb")))
    die("Failed to open %s for writing.", argv[2]);

  info = vpx_video_reader_get_info(reader);

  decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
  if (!decoder)
    die("Unknown input codec.");

  printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));

  if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
    die_codec(&codec, "Failed to initialize decoder");

  while (vpx_video_reader_read_frame(reader)) {
    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img = NULL;
    size_t frame_size = 0;
    const unsigned char *frame = vpx_video_reader_get_frame(reader,
                                                            &frame_size);
    if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
      die_codec(&codec, "Failed to decode frame");

    while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) {
      unsigned char digest[16];

      get_image_md5(img, digest);
      print_md5(outfile, digest);
      fprintf(outfile, "  img-%dx%d-%04d.i420\n",
              img->d_w, img->d_h, ++frame_cnt);
    }
  }

  printf("Processed %d frames.\n", frame_cnt);
  if (vpx_codec_destroy(&codec))
    die_codec(&codec, "Failed to destroy codec.");

  vpx_video_reader_close(reader);

  fclose(outfile);
  return EXIT_SUCCESS;
}
Exemplo n.º 10
0
JNIEXPORT void Java_ryulib_VideoZip_VPX_InitDecoder(JNIEnv* env,
		jclass clazz, jint handle)
{
	RyuVPX *pHandle = (RyuVPX *) handle;

	int flags = 0;
	vpx_codec_dec_init(&pHandle->codec, interfaceDec, &pHandle->cfgDec, flags);
}
Exemplo n.º 11
0
Stream* create_stream(uint8_t *header, size_t net_packet_size, size_t net_buf_size) {
  Stream *stream = (Stream*)malloc(sizeof(Stream));

  size_t *size_t_ptr;
  uint8_t *uint8_t_ptr;

  stream->net_packet_size = net_packet_size;
  stream->net_buf_fill = 0;
  stream->net_buf_size = net_buf_size;
  proc_info("Net Buf Size %u", (unsigned int)stream->net_buf_size);
  stream->net_buf = (uint8_t*)calloc(stream->net_buf_size, sizeof(uint8_t));

  stream->reader = vpx_video_stream_reader_open(header);
  if (!stream->reader)
    proc_die("Failed to create new stream");

  stream->info = vpx_video_stream_reader_get_info(stream->reader);
  proc_info("Frame Width %u\n", stream->info->frame_width);
  proc_info("Frame Height %u\n", stream->info->frame_height);
  // proc_info("Frame Count %u\n", stream->info->frame_count);

  // stream->gl_luma_buf_fill = 0;
  // stream->gl_luma_buf_size = stream->info->frame_width * stream->info->frame_height;
  // // proc_info("GL Buf Size %u", (unsigned int)stream->gl_buf_size);
  // stream->gl_luma_buf = (uint8_t*)calloc(stream->gl_luma_buf_size, sizeof(uint8_t));
  //
  // stream->gl_chromaB_buf_fill = 0;
  // stream->gl_chromaB_buf_size = stream->info->frame_width/2 * stream->info->frame_height/2;
  // // proc_info("GL Buf Size %u", (unsigned int)stream->gl_buf_size);
  // stream->gl_chromaB_buf = (uint8_t*)calloc(stream->gl_chromaB_buf_size, sizeof(uint8_t));
  //
  // stream->gl_chromaR_buf_fill = 0;
  // stream->gl_chromaR_buf_size = stream->info->frame_width/2 * stream->info->frame_height/2;
  // // proc_info("GL Buf Size %u", (unsigned int)stream->gl_buf_size);
  // stream->gl_chromaR_buf = (uint8_t*)calloc(stream->gl_chromaR_buf_size, sizeof(uint8_t));

  stream->decoder = get_vpx_decoder_by_fourcc(stream->info->codec_fourcc);
  if (!stream->decoder)
    proc_die("Unknown input codec.");

  printf("Using %s\r\n", vpx_codec_iface_name(stream->decoder->codec_interface()));

  if (vpx_codec_dec_init(&stream->codec, stream->decoder->codec_interface(), NULL, 0))
    die_codec(&stream->codec, "Failed to initialize decoder.");

  // stream->postproc = (vp8_postproc_cfg_t){
  //   VP8_DEBLOCK | VP8_DEMACROBLOCK,
  //   4, // strength of deblocking, valid range [0, 16]
  //   0
  // };
  //
  // if(vpx_codec_control(&stream->codec, VP8_SET_POSTPROC, &stream->postproc))
  //   die_codec(&stream->codec, "Failed to turn on postproc");

  return stream;
}
Exemplo n.º 12
0
	int VPXEncoder::InitDecoder()
	{
		_vpxDecoder = new vpx_codec_ctx_t();

		/* Initialize decoder */
		if (vpx_codec_dec_init(_vpxDecoder, (vpx_codec_vp8_dx()), NULL, 0)) {
			printf("Failed to initialize libvpx decoder.\n");
			return -1;
		}
	}
Exemplo n.º 13
0
static int dec_initialize_impl(MSFilter *f){
	DecState *s = (DecState *)f->data;
	vpx_codec_dec_cfg_t cfg;
		
	memset(&cfg, 0, sizeof(cfg));
	cfg.threads = ms_factory_get_cpu_count(f->factory);
	if (vpx_codec_dec_init(&s->codec, s->iface, &cfg, s->flags)){
		ms_error("Failed to initialize VP8 decoder");
		return -1;
	}
	return 0;
}
/*
 * Method:    codec_dec_init
 */
JNIEXPORT jint JNICALL
Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1dec_1init
    (JNIEnv *env,
     jclass clazz,
     jlong context,
     jint iface,
     jlong cfg,
     jlong flags)
{
    return (jint) vpx_codec_dec_init(
                        (vpx_codec_ctx_t *) (intptr_t) context,
                        GET_INTERFACE(iface),
                        (vpx_codec_dec_cfg_t *) (intptr_t) cfg,
                        (vpx_codec_flags_t) flags);
}
Exemplo n.º 15
0
static switch_status_t init_decoder(switch_codec_t *codec)
{
	vpx_context_t *context = (vpx_context_t *)codec->private_info;
	vpx_codec_dec_cfg_t cfg = {0, 0, 0};
	vpx_codec_flags_t dec_flags = 0;

	if (context->flags & SWITCH_CODEC_FLAG_DECODE && !context->decoder_init) {
		vp8_postproc_cfg_t ppcfg;
		
		//if (context->decoder_init) {
		//	vpx_codec_destroy(&context->decoder);
		//	context->decoder_init = 0;
		//}

		cfg.threads = switch_core_cpu_count();

		if (!context->is_vp9) { // vp8 only
			dec_flags = VPX_CODEC_USE_POSTPROC;
		}

		if (vpx_codec_dec_init(&context->decoder, context->decoder_interface, &cfg, dec_flags) != VPX_CODEC_OK) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error: [%d:%s]\n", context->encoder.err, context->encoder.err_detail);
			return SWITCH_STATUS_FALSE;
		}

		
		context->last_ts = 0;
		context->last_received_timestamp = 0;
		context->last_received_complete_picture = 0;
		context->decoder_init = 1;
		context->got_key_frame = 0;
		context->got_start_frame = 0;
		// the types of post processing to be done, should be combination of "vp8_postproc_level"
		ppcfg.post_proc_flag = VP8_DEBLOCK;//VP8_DEMACROBLOCK | VP8_DEBLOCK;
		// the strength of deblocking, valid range [0, 16]
		ppcfg.deblocking_level = 1;
		// Set deblocking settings
		vpx_codec_control(&context->decoder, VP8_SET_POSTPROC, &ppcfg);

		if (context->vpx_packet_buffer) {
			switch_buffer_zero(context->vpx_packet_buffer);
		} else {
			switch_buffer_create_dynamic(&context->vpx_packet_buffer, 512, 512, 0);
		}
	}

	return SWITCH_STATUS_SUCCESS;
}
Exemplo n.º 16
0
	bool VideoDecoderVPX::_initialize()
	{        		
        int flags = 0;
        vpx_codec_err_t err_dec_init = vpx_codec_dec_init( &m_codec, vpx_interface, NULL, flags);

        if( err_dec_init != VPX_CODEC_OK )
        {
            LOGGER_ERROR(m_serviceProvider)("VideoDecoderVPX::_initialize vpx_codec_dec_init %d"
                , err_dec_init
                );
            
            return false;
        }

		return true;
	}
Exemplo n.º 17
0
status_t SoftVPX::initDecoder() {
    mCtx = new vpx_codec_ctx_t;
    vpx_codec_err_t vpx_err;
    vpx_codec_dec_cfg_t cfg;
    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
    cfg.threads = GetCPUCoreCount();
    if ((vpx_err = vpx_codec_dec_init(
                (vpx_codec_ctx_t *)mCtx,
                 mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo,
                 &cfg, 0))) {
        ALOGE("on2 decoder failed to initialize. (%d)", vpx_err);
        return UNKNOWN_ERROR;
    }

    return OK;
}
Exemplo n.º 18
0
int rxs_decoder_init(rxs_decoder* dec) {

  vpx_codec_err_t err;

  if (!dec) { return -1; } 

  err = vpx_codec_dec_init(&dec->ctx, vpx_dx_interface, NULL, 0);
  if (err) {
    printf("Error: cannot initialize the decoder: %s.\n", vpx_codec_err_to_string(err));
    return -2; 
  }

  dec->img = NULL;

  return 0;
}
Exemplo n.º 19
0
      struct DecInputContext load(char const *filename) {

        FILE *infile;
        const VpxInterface *interface = NULL;
        vpx_codec_dec_cfg_t cfg = {0, 0, 0};
        int dec_flags = 0;

        infile = fopen(filename, "rb");

        if (!infile) {
          fatal("Failed to open file '%s'", filename);
        }

        struct DecInputContext input;
        vpx_codec_ctx_t *decoder = (vpx_codec_ctx_t*)calloc(1, sizeof(vpx_codec_ctx_t));;
        struct VpxInputContext *vpx_ctx = (VpxInputContext*)calloc(1, sizeof(VpxInputContext));
        struct WebmInputContext *webm_ctx = (WebmInputContext*)calloc(1, sizeof(WebmInputContext));
        memset(&(input), 0, sizeof(input));
        input.vpx_ctx = vpx_ctx;
        input.webm_ctx = webm_ctx;
        input.decoder = decoder;
        input.file = infile;


        input.vpx_ctx->file = infile;
        if(file_is_webm(input.webm_ctx, input.vpx_ctx))
          input.vpx_ctx->file_type = FILE_TYPE_WEBM;
        else
          fatal("Input isn't a webm!");

        if(webm_guess_framerate(input.webm_ctx, input.vpx_ctx)) {
          fatal("Failed to guess framerate!");
        }

        interface = get_vpx_decoder_by_fourcc(input.vpx_ctx->fourcc);

        if(!interface)
          interface = get_vpx_decoder_by_index(0);

        if(vpx_codec_dec_init(input.decoder, interface->codec_interface(), &cfg, dec_flags)) {
          fatal("Failed to initialize decoder: %s\n", vpx_codec_error(input.decoder));
        }

        return input;

      }
Exemplo n.º 20
0
static pj_status_t pj_vpx_decoder_open(vpx_private *vpx) {
    vpx_codec_flags_t flags = 0;
    vpx_codec_dec_cfg_t cfg;
    int res;

    cfg.threads = 1;
    cfg.h = 0;
    cfg.w = 0;

    res = vpx_codec_dec_init(&vpx->decoder, vpx_codec_vp8_dx(), &cfg, flags);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1, (THIS_FILE, "Failed to init vpx decoder : %s", vpx_codec_err_to_string(res)));
        return PJ_ENOMEM;
    }

    return PJ_SUCCESS;
}
nsresult
SoftwareWebMVideoDecoder::Init(unsigned int aWidth, unsigned int aHeight)
{
  vpx_codec_iface_t* dx = nullptr;
  switch(mReader->GetVideoCodec()) {
    case NESTEGG_CODEC_VP8:
      dx = vpx_codec_vp8_dx();
      break;
    case NESTEGG_CODEC_VP9:
      dx = vpx_codec_vp9_dx();
      break;
  }
  if (!dx || vpx_codec_dec_init(&mVPX, dx, nullptr, 0)) {
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}
Exemplo n.º 22
0
static void dec_init(MSFilter *f) {
	DecState *s=(DecState *)ms_new(DecState,1);

	ms_message("Using %s\n",vpx_codec_iface_name(interface));

	/* Initialize codec */
	if(vpx_codec_dec_init(&s->codec, interface, NULL, 0))
		ms_error("Failed to initialize decoder");

	s->curframe = NULL;
	s->last_error_reported_time = 0;
	s->yuv_width = 0;
	s->yuv_height = 0;
	s->yuv_msg = 0;
	ms_queue_init(&s->q);
	s->first_image_decoded = FALSE;
	f->data = s;
	ms_video_init_average_fps(&s->fps, "VP8 decoder: FPS: %f");
}
Exemplo n.º 23
0
struct vpx_context *init_decoder(int width, int height, const char *colorspace)
{
	int flags = 0;
	int err = 0;
	vpx_codec_iface_t *codec_iface = NULL;
	struct vpx_context *ctx = malloc(sizeof(struct vpx_context));
	if (ctx == NULL)
		return NULL;
	codec_iface = vpx_codec_vp8_dx();
	memset(ctx, 0, sizeof(struct vpx_context));
	err = vpx_codec_dec_init(&ctx->codec, codec_iface, NULL, flags);
	if (err) {
		codec_error(&ctx->codec, "vpx_codec_dec_init");
		printf("vpx_codec_dec_init(..) failed with error %d\n", err);
		free(ctx);
		return NULL;
	}
	ctx->width = width;
	ctx->height = height;
	return ctx;
}
Exemplo n.º 24
0
JNIEXPORT jint Java_ryulib_VideoZip_VPX_OpenDecoder(JNIEnv* env,
		jclass clazz, jint width, jint height)
{
	RyuVPX *pHandle = (RyuVPX *) malloc(sizeof(RyuVPX));

	pHandle->errorCode = 0;

	pHandle->cfgDec.w = width;
	pHandle->cfgDec.h = height;
	pHandle->cfgDec.threads = 16;

	int flags = 0;

	if (vpx_codec_dec_init(&pHandle->codec, interfaceDec, &pHandle->cfgDec, flags)) {
		pHandle->errorCode = _Error_Init_VideoCodec;
		goto EXIT;
	}

EXIT:

	return pHandle;
}
Exemplo n.º 25
0
bool VPXDecoder::init(vpx_codec_iface_t *iface) {
	// Destroy any old context
	if (_initialized) {
		vpx_codec_destroy(&_context);
		_initialized = false;
	}

	// Set up the config params
	// TODO: More threads?
	vpx_codec_dec_cfg config;
	memset(&config, 0, sizeof(config));
	config.threads = 1;

	// Try to perform the initialization
	vpx_codec_err_t result = vpx_codec_dec_init(&_context, iface, &config, 0);
	if (result != VPX_CODEC_OK)
		return false;

	// All good
	_initialized = true;
	return true;
}
Exemplo n.º 26
0
// Initializes VPX decoder
static int
vpx_init(AVCodecContext *avctx, const struct vpx_codec_iface *iface)
{
    Decoder * const decoder = avctx->opaque;
    vpx_codec_err_t err;

    memset(&decoder->config, 0, sizeof(decoder->config));
    decoder->config.threads = MVT_MIN(avctx->thread_count, 16);

    err = vpx_codec_dec_init(&decoder->decoder, iface, &decoder->config, 0);
    if (err != VPX_CODEC_OK)
        goto error_init_decoder;
    decoder->is_open = true;

    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
    return 0;

    /* ERRORS */
error_init_decoder:
    mvt_error("failed to initialize decoder: %s",
        vpx_codec_error(&decoder->decoder));
    return AVERROR(EINVAL);
}
Exemplo n.º 27
0
// returns 0 on success, -1 on error
static int init_video(nestegg *nestegg_ctx, int track, video_context *video_ctx)
{
    nestegg_video_params video_params;
    nestegg_track_video_params(nestegg_ctx, track, &video_params);
    assert(video_params.stereo_mode == NESTEGG_VIDEO_MONO);

    if (vpx_codec_dec_init(&(video_ctx->vpx_ctx), vpx_codec_vp8_dx(), NULL, 0))
    {
        printf("Error: failed to initialize libvpx\n");
        return -1;
    }
    video_ctx->width = video_params.width;
    video_ctx->height = video_params.height;
    video_ctx->display_width = video_params.display_width;
    video_ctx->display_height = video_params.display_height;
    nestegg_track_default_duration(nestegg_ctx, track, &(video_ctx->frame_delay));
    printf("Video track: resolution=%i*%i, display resolution=%i*%i, %.2f frames/second\n",
            video_params.width, video_params.height,
            video_params.display_width, video_params.display_height,
            1000000000.0 / video_ctx->frame_delay);
    video_ctx->packet_queue = queue_init(PACKET_QUEUE_SIZE);
    video_ctx->frame_queue = queue_init(FRAME_QUEUE_SIZE);
    return 0;
}
Exemplo n.º 28
0
int main(int argc, char **argv) {
  int frame_cnt = 0;
  FILE *outfile = NULL;
  vpx_codec_ctx_t codec;
  const VpxInterface *decoder = NULL;
  VpxVideoReader *reader = NULL;
  const VpxVideoInfo *info = NULL;
  int n = 0;
  int m = 0;
  int is_range = 0;
  char *nptr = NULL;

  exec_name = argv[0];

  if (argc != 4)
    die("Invalid number of arguments.");

  reader = vpx_video_reader_open(argv[1]);
  if (!reader)
    die("Failed to open %s for reading.", argv[1]);

  if (!(outfile = fopen(argv[2], "wb")))
    die("Failed to open %s for writing.", argv[2]);

  n = strtol(argv[3], &nptr, 0);
  m = strtol(nptr + 1, NULL, 0);
  is_range = (*nptr == '-');
  if (!n || !m || (*nptr != '-' && *nptr != '/'))
    die("Couldn't parse pattern %s.\n", argv[3]);

  info = vpx_video_reader_get_info(reader);

  decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
  if (!decoder)
    die("Unknown input codec.");

  printf("Using %s\n", vpx_codec_iface_name(decoder->interface()));

  if (vpx_codec_dec_init(&codec, decoder->interface(), NULL, 0))
    die_codec(&codec, "Failed to initialize decoder.");

  while (vpx_video_reader_read_frame(reader)) {
    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img = NULL;
    size_t frame_size = 0;
    int skip;
    const unsigned char *frame = vpx_video_reader_get_frame(reader,
                                                            &frame_size);
    if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
      die_codec(&codec, "Failed to decode frame.");

    ++frame_cnt;

    skip = (is_range && frame_cnt >= n && frame_cnt <= m) ||
           (!is_range && m - (frame_cnt - 1) % m <= n);

    if (!skip) {
      putc('.', stdout);

      while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL)
        vpx_img_write(img, outfile);
    } else {
      putc('X', stdout);
    }

    fflush(stdout);
  }

  printf("Processed %d frames.\n", frame_cnt);
  if (vpx_codec_destroy(&codec))
    die_codec(&codec, "Failed to destroy codec.");

  printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
         info->frame_width, info->frame_height, argv[2]);

  vpx_video_reader_close(reader);
  fclose(outfile);

  return EXIT_SUCCESS;
}
Exemplo n.º 29
0
/*****************************************************************************
 * Open: probe the decoder
 *****************************************************************************/
static int Open(vlc_object_t *p_this)
{
    decoder_t *dec = (decoder_t *)p_this;
    const struct vpx_codec_iface *iface;
    int vp_version;

    switch (dec->fmt_in.i_codec)
    {
#ifdef ENABLE_VP8_DECODER
    case VLC_CODEC_VP8:
        iface = &vpx_codec_vp8_dx_algo;
        vp_version = 8;
        break;
#endif
#ifdef ENABLE_VP9_DECODER
    case VLC_CODEC_VP9:
        iface = &vpx_codec_vp9_dx_algo;
        vp_version = 9;
        break;
#endif
    default:
        return VLC_EGENERIC;
    }

    decoder_sys_t *sys = malloc(sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;
    dec->p_sys = sys;

    struct vpx_codec_dec_cfg deccfg = {
        .threads = __MIN(vlc_GetCPUCount(), 16)
    };

    msg_Dbg(p_this, "VP%d: using libvpx version %s (build options %s)", 
        vp_version, vpx_codec_version_str(), vpx_codec_build_config());

    if (vpx_codec_dec_init(&sys->ctx, iface, &deccfg, 0) != VPX_CODEC_OK) {
        const char *error = vpx_codec_error(&sys->ctx);
        msg_Err(p_this, "Failed to initialize decoder: %s\n", error);
        free(sys);
        return VLC_EGENERIC;;
    }

    dec->pf_decode_video = Decode;

    dec->fmt_out.i_cat = VIDEO_ES;
    dec->fmt_out.video.i_width = dec->fmt_in.video.i_width;
    dec->fmt_out.video.i_height = dec->fmt_in.video.i_height;
    dec->fmt_out.i_codec = VLC_CODEC_I420;
    dec->b_need_packetized = true;

    return VLC_SUCCESS;
}

/*****************************************************************************
 * Close: decoder destruction
 *****************************************************************************/
static void Close(vlc_object_t *p_this)
{
    decoder_t *dec = (decoder_t *)p_this;
    decoder_sys_t *sys = dec->p_sys;

    /* Free our PTS */
    const void *iter = NULL;
    for (;;) {
        struct vpx_image *img = vpx_codec_get_frame(&sys->ctx, &iter);
        if (!img)
            break;
        free(img->user_priv);
    }

    vpx_codec_destroy(&sys->ctx);

    free(sys);
}
Exemplo n.º 30
0
int main_loop(int argc, const char **argv_) {
  vpx_codec_ctx_t       decoder;
  char                  *fn = NULL;
  int                    i;
  uint8_t               *buf = NULL;
  size_t                 bytes_in_buffer = 0, buffer_size = 0;
  FILE                  *infile;
  int                    frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int                    do_md5 = 0, progress = 0;
  int                    stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int                    arg_skip = 0;
  int                    ec_enabled = 0;
  const VpxInterface *interface = NULL;
  const VpxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg               arg;
  char                   **argv, **argi, **argj;

  int                     single_file;
  int                     use_y4m = 1;
  vpx_codec_dec_cfg_t     cfg = {0};
#if CONFIG_VP8_DECODER
  vp8_postproc_cfg_t      vp8_pp_cfg = {0};
  int                     vp8_dbg_color_ref_frame = 0;
  int                     vp8_dbg_color_mb_modes = 0;
  int                     vp8_dbg_color_b_modes = 0;
  int                     vp8_dbg_display_mv = 0;
#endif
  int                     frames_corrupted = 0;
  int                     dec_flags = 0;
  int                     do_scale = 0;
  vpx_image_t             *scaled_img = NULL;
  int                     frame_avail, got_data;
  int                     num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = {0};

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = {0};
  FILE *outfile = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct VpxDecInputContext input = {0};
  struct VpxInputContext vpx_input_ctx = {0};
  struct WebmInputContext webm_ctx = {0};
  input.vpx_input_ctx = &vpx_input_ctx;
  input.webm_ctx = &webm_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &codecarg, argi)) {
      interface = get_vpx_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi))
      outfile_pattern = arg.val;
    else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
    } else if (arg_match(&arg, &flipuvarg, argi))
      flipuv = 1;
    else if (arg_match(&arg, &noblitarg, argi))
      noblit = 1;
    else if (arg_match(&arg, &progressarg, argi))
      progress = 1;
    else if (arg_match(&arg, &limitarg, argi))
      stop_after = arg_parse_uint(&arg);
    else if (arg_match(&arg, &skiparg, argi))
      arg_skip = arg_parse_uint(&arg);
    else if (arg_match(&arg, &postprocarg, argi))
      postproc = 1;
    else if (arg_match(&arg, &md5arg, argi))
      do_md5 = 1;
    else if (arg_match(&arg, &summaryarg, argi))
      summary = 1;
    else if (arg_match(&arg, &threadsarg, argi))
      cfg.threads = arg_parse_uint(&arg);
    else if (arg_match(&arg, &verbosearg, argi))
      quiet = 0;
    else if (arg_match(&arg, &scalearg, argi))
      do_scale = 1;
    else if (arg_match(&arg, &fb_arg, argi))
      num_external_frame_buffers = arg_parse_uint(&arg);

#if CONFIG_VP8_DECODER
    else if (arg_match(&arg, &addnoise_level, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
      vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &demacroblock_level, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
      vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &deblock, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK;
    } else if (arg_match(&arg, &mfqe, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_MFQE;
    } else if (arg_match(&arg, &pp_debug_info, argi)) {
      unsigned int level = arg_parse_uint(&arg);

      postproc = 1;
      vp8_pp_cfg.post_proc_flag &= ~0x7;

      if (level)
        vp8_pp_cfg.post_proc_flag |= level;
    } else if (arg_match(&arg, &pp_disp_ref_frame, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_ref_frame = flags;
      }
    } else if (arg_match(&arg, &pp_disp_mb_modes, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_mb_modes = flags;
      }
    } else if (arg_match(&arg, &pp_disp_b_modes, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_b_modes = flags;
      }
    } else if (arg_match(&arg, &pp_disp_mvs, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_display_mv = flags;
      }
    } else if (arg_match(&arg, &error_concealment, argi)) {
      ec_enabled = 1;
    }

#endif
    else
      argj++;
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn)
    usage_exit();

  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fprintf(stderr, "Failed to open file '%s'", strcmp(fn, "-") ? fn : "stdin");
    return EXIT_FAILURE;
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.vpx_input_ctx->file = infile;
  if (file_is_ivf(input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_raw(input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "vpxdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      vpx_input_ctx.width, vpx_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr, "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
        fprintf(stderr, "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface)
    interface = get_vpx_decoder_by_index(0);

  dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
  if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (!quiet)
    fprintf(stderr, "%s\n", decoder.name);

#if CONFIG_VP8_DECODER

  if (vp8_pp_cfg.post_proc_flag
      && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) {
    fprintf(stderr, "Failed to configure postproc: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_ref_frame
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_REF_FRAME, vp8_dbg_color_ref_frame)) {
    fprintf(stderr, "Failed to configure reference block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_mb_modes
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_MB_MODES, vp8_dbg_color_mb_modes)) {
    fprintf(stderr, "Failed to configure macro block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_b_modes
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_B_MODES, vp8_dbg_color_b_modes)) {
    fprintf(stderr, "Failed to configure block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_display_mv
      && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv)) {
    fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }
#endif


  if (arg_skip)
    fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size))
      break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (vpx_codec_set_frame_buffer_functions(
            &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer,
            &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              vpx_codec_error(&decoder));
      return EXIT_FAILURE;
    }
  }

  frame_avail = 1;
  got_data = 0;

  /* Decode file */
  while (frame_avail || got_data) {
    vpx_codec_iter_t  iter = NULL;
    vpx_image_t    *img;
    struct vpx_usec_timer timer;
    int                   corrupted;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        vpx_usec_timer_start(&timer);

        if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer,
                             NULL, 0)) {
          const char *detail = vpx_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s",
               frame_in, vpx_codec_error(&decoder));

          if (detail)
            warn("Additional information: %s", detail);
          goto fail;
        }

        vpx_usec_timer_mark(&timer);
        dx_time += vpx_usec_timer_elapsed(&timer);
      }
    }

    vpx_usec_timer_start(&timer);

    got_data = 0;
    if ((img = vpx_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;
    }

    vpx_usec_timer_mark(&timer);
    dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);

    if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
      warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
      goto fail;
    }
    frames_corrupted += corrupted;

    if (progress)
      show_progress(frame_in, frame_out, dx_time);

    if (!noblit && img) {
      const int PLANES_YUV[] = {VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V};
      const int PLANES_YVU[] = {VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U};
      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

      if (do_scale) {
        if (frame_out == 1) {
          // If the output frames are to be scaled to a fixed display size then
          // use the width and height specified in the container. If either of
          // these is set to 0, use the display size set in the first frame
          // header. If that is unavailable, use the raw decoded size of the
          // first decoded frame.
          int display_width = vpx_input_ctx.width;
          int display_height = vpx_input_ctx.height;
          if (!display_width || !display_height) {
            int display_size[2];
            if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
                                  display_size)) {
              // As last resort use size of first frame as display size.
              display_width = img->d_w;
              display_height = img->d_h;
            } else {
              display_width = display_size[0];
              display_height = display_size[1];
            }
          }
          scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, display_width,
                                     display_height, 16);
        }

        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
          vpx_image_scale(img, scaled_img, kFilterBox);
          img = scaled_img;
        }
      }

      if (single_file) {
        if (use_y4m) {
          char buf[Y4M_BUFFER_SIZE] = {0};
          size_t len = 0;
          if (frame_out == 1) {
            // Y4M file header
            len = y4m_write_file_header(buf, sizeof(buf),
                                        vpx_input_ctx.width,
                                        vpx_input_ctx.height,
                                        &vpx_input_ctx.framerate, img->fmt);
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
            } else {
              fputs(buf, outfile);
            }
          }

          // Y4M frame header
          len = y4m_write_frame_header(buf, sizeof(buf));
          if (do_md5) {
            MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
          } else {
            fputs(buf, outfile);
          }
        }

        if (do_md5) {
          update_image_md5(img, planes, &md5_ctx);
        } else {
          write_image_file(img, planes, outfile);
        }
      } else {
        generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                          img->d_w, img->d_h, frame_in);
        if (do_md5) {
          MD5Init(&md5_ctx);
          update_image_md5(img, planes, &md5_ctx);
          MD5Final(md5_digest, &md5_ctx);
          print_md5(md5_digest, outfile_name);
        } else {
          outfile = open_outfile(outfile_name);
          write_image_file(img, planes, outfile);
          fclose(outfile);
        }
      }
    }

    if (stop_after && frame_in >= stop_after)
      break;
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted)
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);

fail:

  if (vpx_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif

  if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM)
    free(buf);

  if (scaled_img) vpx_img_free(scaled_img);

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  free(argv);

  return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS;
}