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> 17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "third_party/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_); 93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (nestegg_ctx_ != NULL) { 94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pkt_ != NULL) { 95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_free_packet(pkt_); 96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_destroy(nestegg_ctx_); 98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual void Init() { 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual void Begin() { 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang input_file_ = OpenTestDataFile(file_name_); 10691037db265ecdd914a26e056cf69207b4f50924ehkuang ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: " 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << file_name_; 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb, 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang input_file_}; 111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ASSERT_FALSE(nestegg_init(&nestegg_ctx_, io, NULL, -1)) 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_init failed"; 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int n; 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_track_count(nestegg_ctx_, &n)) 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "failed to get track count"; 117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (unsigned int i = 0; i < n; i++) { 119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int track_type = nestegg_track_type(nestegg_ctx_, i); 120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_GE(track_type, 0) << "failed to get track type"; 121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (track_type == NESTEGG_TRACK_VIDEO) { 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang video_track_ = i; 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang break; 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FillFrame(); 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual void Next() { 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ++frame_; 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FillFrame(); 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang void FillFrame() { 13791037db265ecdd914a26e056cf69207b4f50924ehkuang ASSERT_TRUE(input_file_ != NULL); 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (chunk_ >= chunks_) { 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int track; 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang do { 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* End of this packet, get another. */ 143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pkt_ != NULL) { 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_free_packet(pkt_); 145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt_ = NULL; 146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int again = nestegg_read_packet(nestegg_ctx_, &pkt_); 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_GE(again, 0) << "nestegg_read_packet failed"; 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!again) { 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang end_of_file_ = true; 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return; 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_packet_track(pkt_, &track)) 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_packet_track failed"; 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } while (track != video_track_); 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_packet_count(pkt_, &chunks_)) 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_packet_count failed"; 161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang chunk_ = 0; 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ASSERT_FALSE(nestegg_packet_data(pkt_, chunk_, &buf_, &buf_sz_)) 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang << "nestegg_packet_data failed"; 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang chunk_++; 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang virtual const uint8_t *cxdata() const { 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return end_of_file_ ? NULL : buf_; 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian virtual size_t frame_size() const { return buf_sz_; } 173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian virtual unsigned int frame_number() const { return frame_; } 174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang protected: 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang std::string file_name_; 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang FILE *input_file_; 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg *nestegg_ctx_; 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang nestegg_packet *pkt_; 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int video_track_; 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int chunk_; 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int chunks_; 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint8_t *buf_; 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang size_t buf_sz_; 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int frame_; 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang bool end_of_file_; 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}; 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} // namespace libvpx_test 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif // TEST_WEBM_VIDEO_SOURCE_H_ 192