c5aaf923d8
the nestegg packet was only freed by subsequent reads Change-Id: Ib687a13907861c7575830783e47a596d85169cf1
192 lines
4.6 KiB
C++
192 lines
4.6 KiB
C++
/*
|
|
* Copyright (c) 2012 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.
|
|
*/
|
|
#ifndef TEST_WEBM_VIDEO_SOURCE_H_
|
|
#define TEST_WEBM_VIDEO_SOURCE_H_
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <new>
|
|
#include <string>
|
|
#include "nestegg/include/nestegg/nestegg.h"
|
|
#include "test/video_source.h"
|
|
|
|
namespace libvpx_test {
|
|
|
|
static int
|
|
nestegg_read_cb(void *buffer, size_t length, void *userdata) {
|
|
FILE *f = reinterpret_cast<FILE *>(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) {
|
|
FILE *f = reinterpret_cast<FILE *>(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(f, (long)offset, whence) ? -1 : 0;
|
|
}
|
|
|
|
|
|
static int64_t
|
|
nestegg_tell_cb(void *userdata) {
|
|
FILE *f = reinterpret_cast<FILE *>(userdata);
|
|
return ftell(f);
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
// This class extends VideoSource to allow parsing of WebM files,
|
|
// so that we can do actual file decodes.
|
|
class WebMVideoSource : public CompressedVideoSource {
|
|
public:
|
|
explicit WebMVideoSource(const std::string &file_name)
|
|
: file_name_(file_name),
|
|
input_file_(NULL),
|
|
nestegg_ctx_(NULL),
|
|
pkt_(NULL),
|
|
video_track_(0),
|
|
chunk_(0),
|
|
chunks_(0),
|
|
buf_(NULL),
|
|
buf_sz_(0),
|
|
frame_(0),
|
|
end_of_file_(false) {
|
|
}
|
|
|
|
virtual ~WebMVideoSource() {
|
|
if (input_file_)
|
|
fclose(input_file_);
|
|
if (nestegg_ctx_ != NULL) {
|
|
if (pkt_ != NULL) {
|
|
nestegg_free_packet(pkt_);
|
|
}
|
|
nestegg_destroy(nestegg_ctx_);
|
|
}
|
|
}
|
|
|
|
virtual void Init() {
|
|
}
|
|
|
|
virtual void Begin() {
|
|
input_file_ = OpenTestDataFile(file_name_);
|
|
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
|
<< file_name_;
|
|
|
|
nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb,
|
|
input_file_};
|
|
ASSERT_FALSE(nestegg_init(&nestegg_ctx_, io, NULL))
|
|
<< "nestegg_init failed";
|
|
|
|
unsigned int n;
|
|
ASSERT_FALSE(nestegg_track_count(nestegg_ctx_, &n))
|
|
<< "failed to get track count";
|
|
|
|
for (unsigned int i = 0; i < n; i++) {
|
|
int track_type = nestegg_track_type(nestegg_ctx_, i);
|
|
ASSERT_GE(track_type, 0) << "failed to get track type";
|
|
|
|
if (track_type == NESTEGG_TRACK_VIDEO) {
|
|
video_track_ = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FillFrame();
|
|
}
|
|
|
|
virtual void Next() {
|
|
++frame_;
|
|
FillFrame();
|
|
}
|
|
|
|
void FillFrame() {
|
|
ASSERT_TRUE(input_file_ != NULL);
|
|
if (chunk_ >= chunks_) {
|
|
unsigned int track;
|
|
|
|
do {
|
|
/* End of this packet, get another. */
|
|
if (pkt_ != NULL) {
|
|
nestegg_free_packet(pkt_);
|
|
pkt_ = NULL;
|
|
}
|
|
|
|
int again = nestegg_read_packet(nestegg_ctx_, &pkt_);
|
|
ASSERT_GE(again, 0) << "nestegg_read_packet failed";
|
|
if (!again) {
|
|
end_of_file_ = true;
|
|
return;
|
|
}
|
|
|
|
ASSERT_FALSE(nestegg_packet_track(pkt_, &track))
|
|
<< "nestegg_packet_track failed";
|
|
} while (track != video_track_);
|
|
|
|
ASSERT_FALSE(nestegg_packet_count(pkt_, &chunks_))
|
|
<< "nestegg_packet_count failed";
|
|
chunk_ = 0;
|
|
}
|
|
|
|
ASSERT_FALSE(nestegg_packet_data(pkt_, chunk_, &buf_, &buf_sz_))
|
|
<< "nestegg_packet_data failed";
|
|
chunk_++;
|
|
}
|
|
|
|
virtual const uint8_t *cxdata() const {
|
|
return end_of_file_ ? NULL : buf_;
|
|
}
|
|
virtual const unsigned int frame_size() const { return buf_sz_; }
|
|
virtual const unsigned int frame_number() const { return frame_; }
|
|
|
|
protected:
|
|
std::string file_name_;
|
|
FILE *input_file_;
|
|
nestegg *nestegg_ctx_;
|
|
nestegg_packet *pkt_;
|
|
unsigned int video_track_;
|
|
unsigned int chunk_;
|
|
unsigned int chunks_;
|
|
uint8_t *buf_;
|
|
size_t buf_sz_;
|
|
unsigned int frame_;
|
|
bool end_of_file_;
|
|
};
|
|
|
|
} // namespace libvpx_test
|
|
|
|
#endif // TEST_WEBM_VIDEO_SOURCE_H_
|