An error occurred while loading the file. Please try again.
-
Deb Mukherjee authored
Cleans up the experiment. Actually uses reduced counts for backward updates, and reduced number of probabilities in the context. No change in bitstream when the experiment is on. Between expt on and off: derfraw300 is down only -0.062% (which is better than when expts were run previously). Change-Id: I55285a049a0c22810bdb42914212ab5a4f8521b5
39a90bc8
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "./webmdec.h"
#include <stdarg.h>
#include "nestegg/include/nestegg/nestegg.h"
static int nestegg_read_cb(void *buffer, size_t length, void *userdata) {
FILE *f = userdata;
if (fread(buffer, 1, length, f) < length) {
if (ferror(f))
return -1;
if (feof(f))
return 0;
}
return 1;
}
static int nestegg_seek_cb(int64_t offset, int whence, void *userdata) {
switch (whence) {
case NESTEGG_SEEK_SET:
whence = SEEK_SET;
break;
case NESTEGG_SEEK_CUR:
whence = SEEK_CUR;
break;
case NESTEGG_SEEK_END:
whence = SEEK_END;
break;
};
return fseek(userdata, (int32_t)offset, whence) ? -1 : 0;
}
static int64_t nestegg_tell_cb(void *userdata) {
return ftell(userdata);
}
static void nestegg_log_cb(nestegg *context,
unsigned int severity,
char const *format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
va_end(ap);
}
int file_is_webm(struct WebmInputContext *webm_ctx,
struct VpxInputContext *vpx_ctx) {
uint32_t i, n;
int track_type = -1;
int codec_id;
nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb, 0};
nestegg_video_params params;
io.userdata = vpx_ctx->file;
if (nestegg_init(&webm_ctx->nestegg_ctx, io, NULL))
goto fail;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
if (nestegg_track_count(webm_ctx->nestegg_ctx, &n))
goto fail;
for (i = 0; i < n; i++) {
track_type = nestegg_track_type(webm_ctx->nestegg_ctx, i);
if (track_type == NESTEGG_TRACK_VIDEO)
break;
else if (track_type < 0)
goto fail;
}
codec_id = nestegg_track_codec_id(webm_ctx->nestegg_ctx, i);
if (codec_id == NESTEGG_CODEC_VP8) {
vpx_ctx->fourcc = VP8_FOURCC_MASK;
} else if (codec_id == NESTEGG_CODEC_VP9) {
vpx_ctx->fourcc = VP9_FOURCC_MASK;
} else {
fatal("Not VPx video, quitting.\n");
}
webm_ctx->video_track = i;
if (nestegg_track_video_params(webm_ctx->nestegg_ctx, i, ¶ms))
goto fail;
vpx_ctx->framerate.denominator = 0;
vpx_ctx->framerate.numerator = 0;
vpx_ctx->width = params.width;
vpx_ctx->height = params.height;
return 1;
fail:
webm_ctx->nestegg_ctx = NULL;
rewind(vpx_ctx->file);
return 0;
}
int webm_read_frame(struct WebmInputContext *webm_ctx,
uint8_t **buffer,
size_t *bytes_in_buffer,
size_t *buffer_size) {
if (webm_ctx->chunk >= webm_ctx->chunks) {
uint32_t track;
do {
/* End of this packet, get another. */
if (webm_ctx->pkt) {
nestegg_free_packet(webm_ctx->pkt);
webm_ctx->pkt = NULL;
}
if (nestegg_read_packet(webm_ctx->nestegg_ctx, &webm_ctx->pkt) <= 0 ||
nestegg_packet_track(webm_ctx->pkt, &track)) {
return 1;
}
} while (track != webm_ctx->video_track);
if (nestegg_packet_count(webm_ctx->pkt, &webm_ctx->chunks))
return 1;
webm_ctx->chunk = 0;
}
if (nestegg_packet_data(webm_ctx->pkt, webm_ctx->chunk,
buffer, bytes_in_buffer)) {
return 1;
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
webm_ctx->chunk++;
return 0;
}
int webm_guess_framerate(struct WebmInputContext *webm_ctx,
struct VpxInputContext *vpx_ctx) {
uint32_t i;
uint64_t tstamp = 0;
/* Check to see if we can seek before we parse any data. */
if (nestegg_track_seek(webm_ctx->nestegg_ctx, webm_ctx->video_track, 0)) {
warn("Failed to guess framerate (no Cues), set to 30fps.\n");
vpx_ctx->framerate.numerator = 30;
vpx_ctx->framerate.denominator = 1;
return 0;
}
/* Guess the framerate. Read up to 1 second, or 50 video packets,
* whichever comes first.
*/
for (i = 0; tstamp < 1000000000 && i < 50;) {
nestegg_packet *pkt;
uint32_t track;
if (nestegg_read_packet(webm_ctx->nestegg_ctx, &pkt) <= 0)
break;
nestegg_packet_track(pkt, &track);
if (track == webm_ctx->video_track) {
nestegg_packet_tstamp(pkt, &tstamp);
++i;
}
nestegg_free_packet(pkt);
}
if (nestegg_track_seek(webm_ctx->nestegg_ctx, webm_ctx->video_track, 0))
goto fail;
vpx_ctx->framerate.numerator = (i - 1) * 1000000;
vpx_ctx->framerate.denominator = (int)(tstamp / 1000);
return 0;
fail:
nestegg_destroy(webm_ctx->nestegg_ctx);
webm_ctx->nestegg_ctx = NULL;
rewind(vpx_ctx->file);
return 1;
}
void webm_free(struct WebmInputContext *webm_ctx) {
if (webm_ctx && webm_ctx->nestegg_ctx) {
if (webm_ctx->pkt)
nestegg_free_packet(webm_ctx->pkt);
nestegg_destroy(webm_ctx->nestegg_ctx);
}
}