1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* 2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * 4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * Use of this source code is governed by a BSD-style license 5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * that can be found in the LICENSE file in the root of the source 6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * tree. An additional intellectual property rights grant can be found 7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * in the file PATENTS. All contributing project authors may 8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * be found in the AUTHORS file in the root of the source tree. 9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */ 10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifndef TEST_WEBM_VIDEO_SOURCE_H_ 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define TEST_WEBM_VIDEO_SOURCE_H_ 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <cstdarg> 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <cstdio> 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <cstdlib> 15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <new> 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <string> 17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "nestegg/include/nestegg/nestegg.h" 18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "test/video_source.h" 19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnamespace libvpx_test { 21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnestegg_read_cb(void *buffer, size_t length, void *userdata) { 24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FILE *f = reinterpret_cast<FILE *>(userdata); 25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (fread(buffer, 1, length, f) < length) { 27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ferror(f)) 28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -1; 29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (feof(f)) 30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 1; 33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnestegg_seek_cb(int64_t offset, int whence, void *userdata) { 38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FILE *f = reinterpret_cast<FILE *>(userdata); 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang switch (whence) { 40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case NESTEGG_SEEK_SET: 41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang whence = SEEK_SET; 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case NESTEGG_SEEK_CUR: 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang whence = SEEK_CUR; 45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang case NESTEGG_SEEK_END: 47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang whence = SEEK_END; 48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang }; 50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return fseek(f, (long)offset, whence) ? -1 : 0; 51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnestegg_tell_cb(void *userdata) { 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FILE *f = reinterpret_cast<FILE *>(userdata); 57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return ftell(f); 58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void 62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangnestegg_log_cb(nestegg *context, unsigned int severity, char const *format, 63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ...) { 64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang va_list ap; 65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang va_start(ap, format); 67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vfprintf(stderr, format, ap); 68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fprintf(stderr, "\n"); 69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang va_end(ap); 70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// This class extends VideoSource to allow parsing of WebM files, 73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// so that we can do actual file decodes. 74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangclass WebMVideoSource : public CompressedVideoSource { 75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang public: 76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang explicit WebMVideoSource(const std::string &file_name) 77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang : file_name_(file_name), 78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang input_file_(NULL), 79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_ctx_(NULL), 80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pkt_(NULL), 81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang video_track_(0), 82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang chunk_(0), 83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang chunks_(0), 84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang buf_(NULL), 85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang buf_sz_(0), 86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang frame_(0), 87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang end_of_file_(false) { 88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual ~WebMVideoSource() { 91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (input_file_) 92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang fclose(input_file_); 93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (nestegg_ctx_) 94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_destroy(nestegg_ctx_); 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual void Init() { 98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual void Begin() { 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang input_file_ = OpenTestDataFile(file_name_); 10291037db265ecdd914a26e056cf69207b4f50924ehkuang ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: " 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << file_name_; 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb, 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang input_file_}; 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_init(&nestegg_ctx_, io, NULL)) 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_init failed"; 109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int n; 111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_track_count(nestegg_ctx_, &n)) 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "failed to get track count"; 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (unsigned int i = 0; i < n; i++) { 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int track_type = nestegg_track_type(nestegg_ctx_, i); 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_GE(track_type, 0) << "failed to get track type"; 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (track_type == NESTEGG_TRACK_VIDEO) { 119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang video_track_ = i; 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FillFrame(); 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual void Next() { 128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ++frame_; 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FillFrame(); 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void FillFrame() { 13391037db265ecdd914a26e056cf69207b4f50924ehkuang ASSERT_TRUE(input_file_ != NULL); 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (chunk_ >= chunks_) { 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int track; 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang do { 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* End of this packet, get another. */ 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (pkt_) 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_free_packet(pkt_); 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int again = nestegg_read_packet(nestegg_ctx_, &pkt_); 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_GE(again, 0) << "nestegg_read_packet failed"; 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!again) { 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang end_of_file_ = true; 146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return; 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_packet_track(pkt_, &track)) 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_packet_track failed"; 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } while (track != video_track_); 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_packet_count(pkt_, &chunks_)) 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_packet_count failed"; 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang chunk_ = 0; 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_packet_data(pkt_, chunk_, &buf_, &buf_sz_)) 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_packet_data failed"; 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang chunk_++; 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual const uint8_t *cxdata() const { 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return end_of_file_ ? NULL : buf_; 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual const unsigned int frame_size() const { return buf_sz_; } 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual const unsigned int frame_number() const { return frame_; } 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang protected: 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang std::string file_name_; 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FILE *input_file_; 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg *nestegg_ctx_; 173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_packet *pkt_; 174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int video_track_; 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int chunk_; 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int chunks_; 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint8_t *buf_; 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang size_t buf_sz_; 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int frame_; 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang bool end_of_file_; 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} // namespace libvpx_test 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif // TEST_WEBM_VIDEO_SOURCE_H_ 186