test public

Dependencies:   HttpServer_snapshot_mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EasyDec_Mov.cpp Source File

EasyDec_Mov.cpp

00001 /* mbed EasyDec_Mov Library
00002  * Copyright (C) 2018 dkato
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "EasyDec_Mov.h"
00018 
00019 #define FourConstant(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
00020 
00021 #ifndef htonl
00022 #   define htonl(x) __REV(x)
00023 #endif
00024 #ifndef ntohl
00025 #   define ntohl(x) __REV(x)
00026 #endif
00027 
00028 uint8_t * EasyDec_Mov::_videoBuf = NULL;
00029 uint32_t EasyDec_Mov::_videoBufSize = 0;
00030 Callback<void()> EasyDec_Mov::_function = NULL;
00031 
00032 void EasyDec_Mov::attach(Callback<void()> func, uint8_t * video_buf, uint32_t video_buf_size) {
00033     _function = func;
00034     _videoBuf = video_buf;
00035     _videoBufSize = video_buf_size;
00036 }
00037 
00038 bool EasyDec_Mov::AnalyzeHeder(char* p_title, char* p_artist, char* p_album, uint16_t tag_size, FILE* fp) {
00039     Buffer buf;
00040 
00041     if (fp == NULL) {
00042         return false;
00043     }
00044     if (p_title != NULL) {
00045         p_title[0] = '\0';
00046     }
00047     if (p_artist != NULL) {
00048         p_artist[0] = '\0';
00049     }
00050     if (p_album != NULL) {
00051         p_album[0] = '\0';
00052     }
00053 
00054     mov_fp = fp;
00055     availableCount = bufSize;
00056 
00057     frameSizesP = frameSizes;
00058     audioSizesP = audioSizes;
00059 
00060     search(htonl(FourConstant('s', 't', 's', 'z')));
00061     fseek(mov_fp, 8, SEEK_CUR);
00062     fread(&buf, sizeof(Buffer), 1, mov_fp);
00063     numOfFrames = htonl(buf.value);
00064     stszAddress = ftell(mov_fp);
00065     fread(&buf, sizeof(Buffer), 1, mov_fp);
00066 
00067     search(htonl(FourConstant('s', 't', 'c', 'o')));
00068     fseek(mov_fp, 4, SEEK_CUR);
00069     fread(&buf, sizeof(Buffer), 1, mov_fp);
00070     if (numOfFrames != htonl(buf.value)) {
00071         return false;
00072     }
00073     fread(&buf, sizeof(Buffer), 1, mov_fp);
00074     stcoAddress = ftell(mov_fp);
00075     lastFrameAddress = htonl(buf.value);
00076 
00077     fillCaches();
00078 
00079     _video_flg = true;
00080 
00081     return true;
00082 }
00083 
00084 size_t EasyDec_Mov::GetNextData(void *buf, size_t len) {
00085     size_t ret;
00086     uint32_t rest_size = 0;
00087     uint32_t aSize = *audioSizesP;
00088 
00089     if (numOfFrames <= 0) {
00090         return 0;
00091     }
00092 
00093     if (_video_flg) {
00094         _video_flg = false;
00095         if ((_videoBuf == NULL) || (*frameSizesP > _videoBufSize)) {
00096             fseek(mov_fp, *frameSizesP, SEEK_CUR);
00097         } else {
00098             fread(_videoBuf, 1, *frameSizesP, mov_fp);
00099             if (_function) {
00100                 _function();
00101             }
00102         }
00103         frameSizesP++;
00104     }
00105 
00106     if ((int)aSize < 0) {
00107         ret = 0;
00108     } else {
00109         if (aSize > len) {
00110             rest_size = aSize - len;
00111             *audioSizesP = rest_size;
00112             aSize = len;
00113         }
00114         if (buf == NULL) {
00115             fseek(mov_fp, aSize, SEEK_CUR);
00116             ret = aSize;
00117         } else {
00118             ret = (uint32_t)fread(buf, 1, aSize, mov_fp);
00119         }
00120     }
00121     if (rest_size == 0) {
00122         _video_flg = true;
00123         audioSizesP++;
00124         if (--availableCount == 0) {
00125             fillCaches();
00126         }
00127         numOfFrames--;
00128     }
00129 
00130     return ret;
00131 }
00132 
00133 uint16_t EasyDec_Mov::GetChannel() {
00134     return 2;
00135 }
00136 
00137 uint16_t EasyDec_Mov::GetBlockSize() {
00138     return 16;
00139 }
00140 
00141 uint32_t EasyDec_Mov::GetSamplingRate() {
00142     return 44100;
00143 }
00144 
00145 void EasyDec_Mov::search(uint32_t pattern) {
00146     Buffer buf;
00147     uint8_t first = pattern & 0xFF;
00148     buf.value = 0;
00149     while (true) {
00150         size_t size = fread(buf.array, sizeof(int8_t), 1, mov_fp);
00151         if (size == 0) {
00152             return;
00153         }
00154         if (buf.array[0] == first) {
00155             fread(&buf.array[1], sizeof(int8_t), 3, mov_fp);
00156             if (buf.value == pattern) {
00157                 break;
00158             }
00159         }
00160     }
00161 }
00162 
00163 void EasyDec_Mov::fillCaches() {
00164     Buffer buf[bufSize];
00165     Buffer *bufP = buf;
00166     uint32_t lastFrame = lastFrameAddress;
00167 
00168     fseek(mov_fp, stszAddress, SEEK_SET);
00169     fread(frameSizes, sizeof(uint32_t), bufSize, mov_fp);
00170     stszAddress += sizeof(uint32_t) * bufSize;
00171 
00172     fseek(mov_fp, stcoAddress, SEEK_SET);
00173     stcoAddress += sizeof(uint32_t) * bufSize;
00174     fread(buf, sizeof(Buffer), bufSize, mov_fp);
00175     availableCount = bufSize;
00176     frameSizesP = frameSizes;
00177     audioSizesP = audioSizes;
00178     do {
00179         uint32_t frameAddress = htonl(bufP->value);
00180         *frameSizesP = htonl(*frameSizesP);
00181         *audioSizesP++ = frameAddress - lastFrameAddress - *frameSizesP;
00182         lastFrameAddress = frameAddress;
00183         ++frameSizesP;
00184         ++bufP;
00185     } while (--availableCount);
00186 
00187     fseek(mov_fp, lastFrame, SEEK_SET);
00188     availableCount = bufSize;
00189     frameSizesP = frameSizes;
00190     audioSizesP = audioSizes;
00191 }
00192 
00193