MP4.cpp 3.19 KB
Newer Older
1
/*
xiongziliang committed
2
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
xiongziliang committed
3 4 5
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
xiongziliang committed
6 7 8
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
xiongziliang committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
 */

#ifdef ENABLE_MP4
#include "MP4.h"
#include "Util/File.h"
#include "Util/logger.h"
#include "Common/config.h"
using namespace toolkit;
namespace mediakit {

static struct mov_buffer_t s_io = {
        [](void* ctx, void* data, uint64_t bytes) {
            MP4File *thiz = (MP4File *)ctx;
            return thiz->onRead(data,bytes);
        },
        [](void* ctx, const void* data, uint64_t bytes){
            MP4File *thiz = (MP4File *)ctx;
            return thiz->onWrite(data,bytes);
        },
        [](void* ctx, uint64_t offset) {
            MP4File *thiz = (MP4File *)ctx;
            return thiz->onSeek(offset);
        },
        [](void* ctx){
            MP4File *thiz = (MP4File *)ctx;
            return thiz->onTell();
        }
};

MP4File::Writer MP4File::createWriter(){
    GET_CONFIG(bool, mp4FastStart, Record::kFastStart);
    Writer writer;
    writer.reset(mov_writer_create(&s_io,this,mp4FastStart ? MOV_FLAG_FASTSTART : 0),[](mov_writer_t *ptr){
        if(ptr){
            mov_writer_destroy(ptr);
        }
    });
    if(!writer){
        throw std::runtime_error("写入mp4文件失败!");
    }
    return writer;
}

MP4File::Reader MP4File::createReader(){
    Reader reader;
    reader.reset(mov_reader_create(&s_io,this),[](mov_reader_t *ptr){
        if(ptr){
            mov_reader_destroy(ptr);
        }
    });
    if(!reader){
        throw std::runtime_error("读取mp4文件失败!");
    }
    return reader;
}

#if defined(_WIN32) || defined(_WIN64)
    #define fseek64 _fseeki64
#define ftell64 _ftelli64
#else
#define fseek64 fseek
#define ftell64 ftell
#endif

void MP4File::openFile(const char *file,const char *mode) {
    //创建文件
xiongziliang committed
75
    auto fp = File::create_file(file, mode);
xiongziliang committed
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    if(!fp){
        throw std::runtime_error(string("打开文件失败:") + file);
    }

    GET_CONFIG(uint32_t,mp4BufSize,Record::kFileBufSize);

    //新建文件io缓存
    std::shared_ptr<char> file_buf(new char[mp4BufSize],[](char *ptr){
        if(ptr){
            delete [] ptr;
        }
    });

    if(file_buf){
        //设置文件io缓存
        setvbuf(fp, file_buf.get(), _IOFBF, mp4BufSize);
    }

    //创建智能指针
    _file.reset(fp,[file_buf](FILE *fp) {
        fclose(fp);
    });
}

void MP4File::closeFile() {
    _file = nullptr;
}

int MP4File::onRead(void *data, uint64_t bytes) {
    if (bytes == fread(data, 1, bytes, _file.get())){
        return 0;
    }
    return 0 != ferror(_file.get()) ? ferror(_file.get()) : -1 /*EOF*/;
}

int MP4File::onWrite(const void *data, uint64_t bytes) {
    return bytes == fwrite(data, 1, bytes, _file.get()) ? 0 : ferror(_file.get());
}

int MP4File::onSeek(uint64_t offset) {
    return fseek64(_file.get(), offset, SEEK_SET);
}

uint64_t MP4File::onTell() {
    return ftell64(_file.get());
}

}//namespace mediakit
#endif //NABLE_MP4RECORD