static inline uint32_t getVideoSampleTime(uint8_t *atombuf, uint32_t sampleID) { static uint32_t numSamples, count, duration; static FILE fp; if(sampleID == 0){ numSamples = count = 0; memcpy((void*)&fp, (void*)&video_stts.fp, sizeof(FILE)); } if(numSamples < ++count){ count = 1; numSamples = getSampleSize(atombuf, 8, &fp); duration = getAtomSize(&atombuf[4]); } return duration; }
USE MENU #ifdef USE_MENU void mjpegTouch(int id, uint32_t pointed_chunk) // ? ? ? ? ? ? ? ? ? ? Touch pen interrupt processing { uint32_t firstChunk, prevChunk, prevSamples, samples, totalSamples = 0, jFrameOffset; MY_FILE fp_stsc, fp_stsz, fp_stco, fp_frame, fp_frame_cp; uint8_t atombuf[12]; raw_video_typedef raw; memcpy((void*)&fp_stsc, (void*)&video_stsc.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stsz, (void*)&video_stsz.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stco, (void*)&video_stco.fp, sizeof(MY_FILE)); //DANI memcpy((void*)&fp_frame, (void*)&fp_global, sizeof(MY_FILE)); // debug.printf("\r\npointed_chunk:%d video_stco.numEntry:%d", pointed_chunk, video_stco.numEntry); prevChunk = getSampleSize(atombuf, 12, &fp_stsc); // firstChunk samplesPerChunk sampleDescriptionID ????firstChunk?prevChunk? prevSamples = getAtomSize(&atombuf[4]); // ????samplesPerChunk?prevSamples? firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ????firstChunk while(1){ if(prevChunk <= pointed_chunk && firstChunk >= pointed_chunk){ samples = (firstChunk - pointed_chunk) * prevSamples; totalSamples += (pointed_chunk - prevChunk) * prevSamples; break; } samples = (firstChunk - prevChunk) * prevSamples; totalSamples += samples; prevChunk = firstChunk; // ???firstChunk?prevChunk? prevSamples = getSampleSize(atombuf, 8, &fp_stsc); // samplesPerChunk sampleDescriptionID firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ??firstChunk } my_fseek(&fp_stco, (pointed_chunk - 1) * 4, SEEK_CUR); jFrameOffset = getSampleSize(atombuf, 4, &fp_stco); memcpy((void*)&fp_stco, (void*)&video_stco.fp, sizeof(MY_FILE)); my_fseek(&fp_stco, (pointed_chunk - 1) * 4, SEEK_CUR); // my_fseek(&fp_frame, jFrameOffset, SEEK_SET); memcpy((void*)&fp_frame_cp, (void*)&fp_frame, sizeof(MY_FILE)); //DANI my_fseek(&fp_frame, raw.frame_size, SEEK_CUR); *pv_src.firstChunk = firstChunk; *pv_src.prevChunk = prevChunk; *pv_src.prevSamples = prevSamples; *pv_src.samples = samples; *pv_src.totalSamples = totalSamples; *pv_src.videoStcoCount = pointed_chunk + 1; memcpy((void*)pv_src.fp_video_stsc, (void*)&fp_stsc, sizeof(MY_FILE)); memcpy((void*)pv_src.fp_video_stsz, (void*)&fp_stsz, sizeof(MY_FILE)); memcpy((void*)pv_src.fp_video_stco, (void*)&fp_stco, sizeof(MY_FILE)); memcpy((void*)pv_src.fp_frame, (void*)&fp_frame, sizeof(MY_FILE)); // Sound memcpy((void*)&fp_stsc, (void*)&sound_stsc.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stsz, (void*)&sound_stsz.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stco, (void*)&sound_stco.fp, sizeof(MY_FILE)); //DANI memcpy((void*)&fp_frame, (void*)&fp_global, sizeof(MY_FILE)); // debug.printf("\r\npointed_chunk:%d video_stco.numEntry:%d", pointed_chunk, video_stco.numEntry); prevChunk = getSampleSize(atombuf, 12, &fp_stsc); // firstChunk samplesPerChunk sampleDescriptionID ????firstChunk?prevChunk? prevSamples = getAtomSize(&atombuf[4]); // ????samplesPerChunk?prevSamples? firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ????firstChunk totalSamples = 0; while(1){ if(prevChunk <= pointed_chunk && firstChunk >= pointed_chunk){ samples = (firstChunk - pointed_chunk) * prevSamples; totalSamples += (pointed_chunk - prevChunk) * prevSamples; break; } samples = (firstChunk - prevChunk) * prevSamples; totalSamples += samples; prevChunk = firstChunk; // ???firstChunk?prevChunk? prevSamples = getSampleSize(atombuf, 8, &fp_stsc); // samplesPerChunk sampleDescriptionID firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ??firstChunk } my_fseek(&fp_stco, (pointed_chunk - 1) * 4, SEEK_CUR); *ps_src.firstChunk = firstChunk; *ps_src.prevChunk = prevChunk; *ps_src.prevSamples = prevSamples; *ps_src.samples = samples; *ps_src.soundStcoCount = pointed_chunk; memcpy((void*)ps_src.fp_sound_stsc, (void*)&fp_stsc, sizeof(MY_FILE)); memcpy((void*)ps_src.fp_sound_stsz, (void*)&fp_stsz, sizeof(MY_FILE)); memcpy((void*)ps_src.fp_sound_stco, (void*)&fp_stco, sizeof(MY_FILE)); if(mjpeg_touch.resynch){ return; } /* //DANI if(media.video.width != LCD_WIDTH || media.video.height != LCD_HEIGHT){ LCD_DrawSquare(0, 0, LCD_WIDTH, media.video.startPosY, BLACK); LCD_DrawSquare(0, media.video.startPosY, (LCD_WIDTH - media.video.width) / 2, media.video.height, BLACK); LCD_DrawSquare(media.video.startPosX + media.video.width, media.video.startPosY, (LCD_WIDTH - media.video.width) / 2, media.video.height, BLACK); LCD_DrawSquare(0, media.video.startPosY + media.video.height, LCD_WIDTH, LCD_HEIGHT - (media.video.startPosY + media.video.height), BLACK); } */ int v; for(v = 0;v < media.video.height;v++) { //(&frame_buffer[media.video.startPosX + v * LCD_WIDTH + media.video.startPosY * LCD_WIDTH], 2, media.video.width, &fp_frame_cp); // read_file (FIL *file, uint8_t *buf, uint32_t sizeofbuf) } int curX, prevX, duration = (int)((float)media.video.duration / (float)media.video.timeScale + 0.5f); int time = duration * (float)*pv_src.videoStcoCount / (float)video_stco.numEntry; char timeStr[20]; LCDPutIcon(4, 100, 12, 12, pause_icon_12x12, pause_icon_12x12_alpha); LCDPutIcon(UI_POS_X, UI_POS_Y, 120, 14, seekbar_120x14, seekbar_120x14_alpha); drawBuff->navigation_loop.x = 140; drawBuff->navigation_loop.y = UI_POS_Y; drawBuff->navigation_loop.width = 18; drawBuff->navigation_loop.height = 14; LCDStoreBgImgToBuff(drawBuff->navigation_loop.x, drawBuff->navigation_loop.y, \ drawBuff->navigation_loop.width, drawBuff->navigation_loop.height, drawBuff->navigation_loop.p); Update_Navigation_Loop_Icon(drawBuff, music_control.b.navigation_loop_mode); drawBuff->posision.width = 12; drawBuff->posision.height = 12; drawBuff->posision.x = UI_POS_X + 1; drawBuff->posision.y = UI_POS_Y + 1; prevX = UI_POS_X + 1; LCDStoreBgImgToBuff(prevX, drawBuff->posision.y, \ drawBuff->posision.width, drawBuff->posision.height, drawBuff->posision.p); DRAW_SEEK_CIRCLE((float)time / (float)duration , seek_active_circle_12x12); pcf_typedef pcf; pcf.dst_gram_addr = (uint32_t)frame_buffer; pcf.pixelFormat = PCF_PIXEL_FORMAT_RGB565; pcf.size = 12; pcf.color = WHITE; pcf.colorShadow = GRAY; pcf.alphaSoftBlending = 1; pcf.enableShadow = 1; pcf_font.metrics.hSpacing = 2; char s[10]; SPRINTF(s, "%d/%d", id, fat.fileCnt - 1); LCD_GotoXY(5, MUSIC_INFO_POS_Y + 1); LCDPutString(s, &pcf); DRAW_MOV_TIME_STR(); DRAW_MOV_REMAIN_TIME_STR(); LCD_FRAME_BUFFER_Transmit(LCD_DMA_TRANSMIT_BLOCKING); }
void CMOVAtom::OnProcessMetaData() { BMallocIO *theUncompressedData; uint8 *outBuffer; CMVDAtom *aCMVDAtom = NULL; uint32 compressionID = 0; uint64 descBytesLeft; uint32 Size; descBytesLeft = getAtomSize(); // Check for Compression Type while (descBytesLeft > 0) { AtomBase *aAtomBase = getAtom(theStream); aAtomBase->OnProcessMetaData(); printf("%s [%Ld]\n",aAtomBase->getAtomName(),aAtomBase->getAtomSize()); if (aAtomBase->getAtomSize() > 0) { descBytesLeft = descBytesLeft - aAtomBase->getAtomSize(); } else { printf("Invalid Atom found when reading Compressed Headers\n"); descBytesLeft = 0; } if (dynamic_cast<DCOMAtom *>(aAtomBase)) { // DCOM atom compressionID = dynamic_cast<DCOMAtom *>(aAtomBase)->getCompressionID(); delete aAtomBase; } else { if (dynamic_cast<CMVDAtom *>(aAtomBase)) { // CMVD atom aCMVDAtom = dynamic_cast<CMVDAtom *>(aAtomBase); descBytesLeft = 0; } } } // Decompress data if (compressionID == 'zlib') { Size = aCMVDAtom->getUncompressedSize(); outBuffer = (uint8 *)(malloc(Size)); printf("Decompressing %ld bytes to %ld bytes\n",aCMVDAtom->getBufferSize(),Size); int result = uncompress(outBuffer, &Size, aCMVDAtom->getCompressedData(), aCMVDAtom->getBufferSize()); if (result != Z_OK) { printf("Failed to decompress headers uncompress returned "); switch (result) { case Z_MEM_ERROR: DEBUGGER("Lack of Memory Error\n"); break; case Z_BUF_ERROR: DEBUGGER("Lack of Output buffer space Error\n"); break; case Z_DATA_ERROR: DEBUGGER("Input Data is corrupt or not a compressed set Error\n"); break; } } // Copy uncompressed data into BMAllocIO theUncompressedData = new BMallocIO(); theUncompressedData->SetSize(Size); theUncompressedData->WriteAt(0L,outBuffer,Size); free(outBuffer); delete aCMVDAtom; // reset position on BMAllocIO theUncompressedData->Seek(SEEK_SET,0L); // Assign to Stream theUncompressedStream = theUncompressedData; // All subsequent reads should use theUncompressedStream } }
off_t MDATAtom::getEOF() { return getStreamOffset() + getAtomSize(); }
uint32_t Play_MOV(FIL *mfile) { uint8_t _aucLine[2048]; register uint32_t i, j; int ret = 0; uint32_t fps, frames, prevFrames, sample_time_limit; uint32_t samples, frameDuration, numEntry; uint32_t prevChunkSound, prevSamplesSound, firstChunkSound, samplesSound; uint32_t firstChunk = 0, totalSamples = 0, prevChunk = 0, prevSamples = 0, totalBytes = 0; uint32_t videoStcoCount, soundStcoCount, stco_reads; uint32_t prevSamplesBuff[60]; FILE fp_sound, fp_frame, fp_frame_cp, \ fp_stsc, fp_stsz, fp_stco, \ fp_sound_stsc, fp_sound_stsz, fp_sound_stco; uint8_t fpsCnt = 0; //danko const char fps1Hz[] = "|/-\\"; char timeStr[20]; raw_video_typedef raw; int soundEndFlag = 0; media.sound.flag.process = 0; media.sound.flag.complete = 0; media.video.flag.process = 0; media.video.flag.complete = 0; memcpy((void*)&fp_global, (void*)mfile, sizeof(FIL)); int hasChild = atomHasChild[UDTA]; // atomHasChild[UDTA] = 0; // No child printf("\r\n[Atoms]"); if(collectAtoms(mfile, mfile->fsize, 0) != 0) { printf("\r\nread error file contents."); /// dani f_close(fp); //DANI/// LCDStatusStruct.waitExitKey = 0; atomHasChild[UDTA] = hasChild; // Moje da ima child return -99; } atomHasChild[UDTA] = hasChild; // Moje da ima child printf("\r\n\n[Video Sample Tables]"); printf("\r\nstts:%d", video_stts.numEntry); printf("\r\nstsc:%d", video_stsc.numEntry); printf("\r\nstsz:%d %d", video_stsz.sampleSize, video_stsz.numEntry); printf("\r\nstco:%d", video_stco.numEntry); printf("\r\n\n[Sound Sample Tables]"); printf("\r\nstts:%d", sound_stts.numEntry); printf("\r\nstsc:%d", sound_stsc.numEntry); printf("\r\nstsz:%d %d", sound_stsz.sampleSize, sound_stsz.numEntry); printf("\r\nstco:%d", sound_stco.numEntry); printf("\r\n\n[Video Track]"); printf("\r\nformat:%s", media.video.videoFmtString); printf("\r\ncompression:%s", media.video.videoCmpString); printf("\r\nwidth:%d", media.video.width); printf("\r\nheight:%d", media.video.height); printf("\r\ntimeScale:%d", media.video.timeScale); printf("\r\nduration:%d", media.video.duration); setStrSec(timeStr, (int)((float)media.video.duration / (float)media.video.timeScale + 0.5f)); //Kvo Pravi media.video.frameRate = (int16_t)((float)(media.video.timeScale * video_stsz.numEntry) / media.video.duration + 0.5f); printf("\r\nframe rate:%d", media.video.frameRate); printf("\r\ntime:%s", timeStr); printf("\r\n\n[Sound Track]"); char s[5]; s[4] = '\0'; memcpy(s, (void*)media.sound.format.audioFmtString, 4); printf("\r\ntype:%s", s); printf("\r\nnumChannel:%d", media.sound.format.numChannel); printf("\r\nsampleSize:%d", media.sound.format.sampleSize); printf("\r\nsampleRate:%d", media.sound.format.sampleRate); printf("\r\ntimeScale:%d", media.sound.timeScale); printf("\r\nduration:%d", media.sound.duration); setStrSec(timeStr, (int)((float)media.sound.duration / (float)media.sound.timeScale + 0.5f)); printf("\r\ntime:%s", timeStr); if(media.video.width > LCD_WIDTH || media.video.height > LCD_HEIGHT){ printf("\r\ntoo large video dimension size."); f_close(mfile);// //DANI////////////////////////////LCDStatusStruct.waitExitKey = 0; atomHasChild[UDTA] = hasChild; return 0; //DANI/////////////////RET_PLAY_STOP; } //DANI///////////////// FUNC_VIDEO_BGIMG; media.video.startPosX = (LCD_WIDTH - media.video.width) / 2 - 1; media.video.startPosY = (LCD_HEIGHT - media.video.height) / 2 - 1; media.video.startPosX = media.video.startPosX > 0 ? media.video.startPosX : 0; media.video.startPosY = media.video.startPosY > 0 ? media.video.startPosY : 0; // media.video.height += (media.video.height % 2); // if value is odd number, convert to even printf("\r\nmedia.video.startPosX:%d", media.video.startPosX); printf("\r\nmedia.video.startPosY:%d", media.video.startPosY); printf("\r\nmedia.video.width:%d", media.video.width); printf("\r\nmedia.video.height:%d", media.video.height); //////////////////////////////////////////////////////////////////////// printf("\r\n\n[Play]\n");/*** MotionJPEG Play Process ***/ //Prehw v STEKA f_lseek(mfile, 0); memcpy((void*)&fp_frame, (void*)mfile, sizeof(FIL)); memcpy((void*)&fp_stsz, (void*)&video_stsz.fp, sizeof(FIL)); memcpy((void*)&fp_stco, (void*)&video_stco.fp, sizeof(FIL)); memcpy((void*)&fp_stsc, (void*)&video_stsc.fp, sizeof(FIL)); numEntry = video_stsc.numEntry; fps = frames = prevFrames = 0; totalSamples = firstChunk = prevChunk = prevSamples = 0; if(abs(video_stco.numEntry - sound_stco.numEntry) > 50) { // not interleaved correctly printf("\r\nError!! this is not an interleaved media."); goto EXIT_PROCESS; } else { prevChunk = getSampleSize(atombuf, 12, &fp_stsc); // firstChunk samplesPerChunk sampleDescriptionID // The firstChunk of the first one to prevChunk prevSamples = getAtomSize(&atombuf[4]); //The samplesPerChunk of the first one to prevSamples firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // The second firstChunk samples = firstChunk - prevChunk; } //A 32-bit integer that indicates how long each frame lasts in real time. frameDuration = getVideoSampleTime(atombuf, totalSamples); //Ot time to sample table // SOUND memcpy((void*)&fp_sound_stsz, (void*)&sound_stsz.fp, sizeof(FILE)); memcpy((void*)&fp_sound_stco, (void*)&sound_stco.fp, sizeof(FILE)); memcpy((void*)&fp_sound_stsc, (void*)&sound_stsc.fp, sizeof(FILE)); memcpy((void*)&fp_sound, (void*)mfile, sizeof(FILE)); prevChunkSound = getSampleSize(atombuf, 12, &fp_sound_stsc); // firstChunk samplesPerChunk sampleDescriptionID ????firstChunk?prevChunk? prevSamplesSound = (getAtomSize(&atombuf[4]) / 100) * 100; //The samplesPerChunk of the first ////////////////////////////////////////////////////////////one so not out half of the sound buffer to prevSamples firstChunkSound = getSampleSize(atombuf, 4, &fp_sound_stsc); // ????firstChunk samplesSound = (firstChunkSound - prevChunkSound) * prevSamplesSound; // uint8_t SOUND_BUFFER[38400]; // uint8_t SOUND_BUFFER[12800]; uint16_t soundSampleByte = media.sound.format.sampleSize / 8; uint32_t soundSampleBlocks = soundSampleByte * media.sound.format.numChannel; float timeScaleCoeff = (1.0f / media.video.timeScale) * 100000; dac_intr.fp = &fp_sound; dac_intr.buff = (uint8_t*)frame_buffer; //////////////////////////////////////////////////////////////// TUK ZVUKA e VAV FREIMA //////////////////////////////////////////////////////dac_intr.buff = SOUND_BUFFER; dac_intr.bufferSize = ((media.sound.format.sampleRate / 10) * 2) * soundSampleByte * media.sound.format.numChannel; // kakva chast ot freima e zvuk // if(media.sound.format.sampleSize == 16){ // dac_intr.func = DAC_Buffer_Process_Stereo_S16bit; // } else { // dac_intr.func = DAC_Buffer_Process_Mono_U8bit; // } memset(dac_intr.buff, 0, dac_intr.bufferSize); f_lseek(&fp_sound, getSampleSize(atombuf, 4, &fp_sound_stco)); dac_intr.sound_reads = 0; stco_reads = 1; printf("\r\nframeDuration:%d", frameDuration); TIM_HandleTypeDef Tim1SecHandle, TimDurationHandle; // TIM3 specified in 0.01ms seconds for sample time TimDurationHandle.Instance = TIM_DURATION; HAL_TIM_Base_DeInit(&TimDurationHandle); TimDurationHandle.Init.Period = (100000 * frameDuration) / media.video.timeScale - 1; TimDurationHandle.Init.Prescaler = ((SystemCoreClock / 2) / 100000) * 2 - 1; // 0.01ms TimDurationHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimDurationHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if(HAL_TIM_Base_Init(&TimDurationHandle) != HAL_OK) { while(1); } HAL_TIM_Base_Start(&TimDurationHandle); /* while(1) { if(TIM3_SR_UIF_BB){ TIM3_SR_UIF_BB = 0; HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); TIM3->CNT = 0; } } */ Tim1SecHandle.Instance = TIM_1SEC; HAL_TIM_Base_DeInit(&Tim1SecHandle); Tim1SecHandle.Init.Prescaler = 100 - 1; Tim1SecHandle.Init.Period = 10000 - 1; Tim1SecHandle.Init.RepetitionCounter = (SystemCoreClock / 1000000UL) - 1; Tim1SecHandle.Init.CounterMode = TIM_COUNTERMODE_UP; Tim1SecHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if(HAL_TIM_Base_Init(&Tim1SecHandle) != HAL_OK) { while(1); } HAL_TIM_Base_Start_IT(&Tim1SecHandle); // Video pv_src.firstChunk = &firstChunk; pv_src.prevChunk = &prevChunk; pv_src.prevSamples = &prevSamples; pv_src.samples = &samples; pv_src.totalSamples = &totalSamples; pv_src.videoStcoCount = &videoStcoCount; pv_src.fp_video_stsc = &fp_stsc; pv_src.fp_video_stsz = &fp_stsz; pv_src.fp_video_stco = &fp_stco; pv_src.fp_frame = &fp_frame; // Sound ps_src.firstChunk = &firstChunkSound; ps_src.prevChunk = &prevChunkSound; ps_src.prevSamples = &prevSamplesSound; ps_src.samples = &samplesSound; ps_src.soundStcoCount = &soundStcoCount; ps_src.fp_sound_stsc = &fp_sound_stsc; ps_src.fp_sound_stsz = &fp_sound_stsz; ps_src.fp_sound_stco = &fp_sound_stco; //DANI mjpeg_touch.resynch = 0; //DANI LCD_SetRegion(media.video.startPosX, media.video.startPosY, media.video.startPosX + media.video.width - 1, media.video.startPosY + media.video.height - 1); float limitter; switch(SystemCoreClock){ case 168000000: limitter = 0.91f; break; case 200000000: limitter = 0.93f; break; case 240000000: limitter = 0.96f; break; case 250000000: limitter = 0.98f; break; default: limitter = 0.8f; break; } videoStcoCount = 0, soundStcoCount = 0; //DANI //DANI pcf_font_typedef pcf_font_bak; //DANI if(pcf_font.ext_loaded) //DANI { //DANI memcpy((void*)&pcf_font_bak, (void*)&pcf_font, sizeof(pcf_font_typedef)); //DANI /* internal flash pcf font */ //DANI C_PCFFontInit((uint32_t)internal_flash_pcf_font, (size_t)_sizeof_internal_flash_pcf_font); //DANI PCF_RENDER_FUNC_C_PCF(); //DANI } //DANI BSP_AUDIO_OUT_Init(0, 0, media.sound.format.sampleSize, media.sound.format.numChannel >= 2 ? media.sound.format.sampleRate : media.sound.format.sampleRate / 2); if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_SPEAKER,50, \ media.sound.format.numChannel >= 2 ? media.sound.format.sampleRate : media.sound.format.sampleRate / 2)!=0) {printf("\r\nAudio Init Error..");}; BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); // wm8731_left_headphone_volume_set(121 + vol); //DANI printf("\r\nhaudio_i2s.State:%d", haudio_i2s.State); //HAL_StatusTypeDef errorState; //HAL_I2S_Transmit_DMA(&haudio_i2s, (uint16_t*)dac_intr.buff, DMA_MAX(dac_intr.bufferSize / ( AUDIODATA_SIZE ))); BSP_AUDIO_OUT_Play( (uint16_t*)dac_intr.buff,DMA_MAX(dac_intr.bufferSize / ( AUDIODATA_SIZE ))); Play_WAV(dac_intr.fp,DMA_MAX(dac_intr.bufferSize / ( AUDIODATA_SIZE )),70); //DANI DMA_SOUND_IT_ENABLE; //DANI LCDStatusStruct.waitExitKey = 1; int outflag = 0, count = 0, pause = 0; while(1){ CHUNK_OFFSET_HEAD: for(j = 0;j < samples;j++){ f_lseek(&fp_frame, getSampleSize(atombuf, 4, &fp_stco) ); //Chunk offset atom if(media.video.playJpeg) { //my_fread(prevSamplesBuff, 1, prevSamples * 4, &fp_stsz); f_read(&fp_stsz, prevSamplesBuff, prevSamples * 4,NULL); //Sample Size Atoms } for(i = 0;i < prevSamples;i++) { sample_time_limit = TIM_DURATION->ARR * limitter; frameDuration = getVideoSampleTime(atombuf, ++totalSamples); // get next frame duration //DANKO LCD_SetGramAddr(media.video.startPosX, media.video.startPosY); //DANKO LCD_CMD(0x002C); raw.output_scanline = 0; raw.frame_size = media.video.width * media.video.height * sizeof(uint16_t); raw.rasters = RASTER; raw.buf_size = raw.rasters * media.video.width * sizeof(uint16_t); memcpy((void*)&fp_frame_cp, (void*)&fp_frame, sizeof(FIL)); f_lseek(&fp_frame, raw.frame_size); totalBytes += raw.frame_size; //danko DMA_SOUND_IT_ENABLE; // Enable DAC interrupt uint32_t tim=1; while(tim--)//!TIM3_SR_UIF_BB) { // while TIM3->SR Update Flag is unset //danko if ((raw.output_scanline < media.video.height) && (TIM_DURATION->CNT < sample_time_limit)) { // Uncompress draw rasters if(raw.frame_size < raw.buf_size){ raw.buf_size = raw.frame_size; } //danko while(SpiLcdHandle.State != HAL_SPI_STATE_READY) { //danko if((TIM_DURATION->CNT >= sample_time_limit)){ //danko HAL_DMA_Abort(SpiLcdHandle.hdmatx); //danko SPI_LCD_NSS_PIN_DEASSERT; //danko goto EXIT_LOOP; } } //danko DMA_SOUND_IT_DISABLE; //danko my_fread((void*)LINE_BUFFER, 1, raw.buf_size, &fp_frame_cp); ////////////jpeg_decode(&fp_frame_cp, IMAGE_WIDTH, _aucLine, Jpeg_CallbackFunction); //danko DMA_SOUND_IT_ENABLE; //danko SPI_LCD_NSS_PIN_ASSERT; //danko SPI_LCD_RS_PIN_DEASSERT; //!!! HAL_SPI_Transmit_DMA(&SpiLcdHandle, (uint8_t*)LINE_BUFFER, raw.buf_size / sizeof(uint16_t)); raw.frame_size -= raw.buf_size; raw.output_scanline += raw.rasters; if((abs(soundStcoCount - videoStcoCount) > 1) && !soundEndFlag) { // correct synch unmatch if(soundStcoCount >= (sound_stco.numEntry - 2) || videoStcoCount >= (video_stco.numEntry - 2)) {goto EXIT_PROCESS;} //danko mjpeg_touch.resynch = 1; //danko mjpeg_touch.resynch_entry = soundStcoCount > videoStcoCount ? videoStcoCount : soundStcoCount; printf("\r\n*synch unmatch at video_stco:%d sound_stco:%d\n", videoStcoCount, soundStcoCount); //danko DMA_SOUND_IT_DISABLE; // Disable DAC interrupt //danko mjpegTouch(id, mjpeg_touch.resynch_entry); //Touch pen interrupt processing samples /= prevSamples; //danko mjpeg_touch.resynch = 0; getVideoSampleTime(atombuf, 0); // reset sample time getVideoSampleTime(atombuf, totalSamples); // get next sample time dac_intr.sound_reads = prevSamplesSound * soundSampleBlocks; // fill DAC buffer videoStcoCount -= 2, soundStcoCount -= 2; goto CHUNK_OFFSET_HEAD; } if(dac_intr.sound_reads >= (prevSamplesSound * soundSampleBlocks)) { if(++soundStcoCount < sound_stco.numEntry) { soundEndFlag = 0; totalBytes += dac_intr.sound_reads; //my_fseek(dac_intr.fp, getSampleSize(atombuf, 4, &fp_sound_stco), SEEK_SET); f_lseek(dac_intr.fp, getSampleSize(atombuf, 4, &fp_sound_stco)); dac_intr.sound_reads = 0; if(++stco_reads > samplesSound){ stco_reads = 0; prevChunkSound = firstChunkSound; // ???firstChunk?prevChunk? prevSamplesSound = getSampleSize(atombuf, 12, &fp_sound_stsc); // samplesPerChunk sampleDescriptionID firstChunkSound = getAtomSize(&atombuf[8]); // ??firstChunk samplesSound = firstChunkSound - prevChunkSound; // The number of samples of the next time playback chunk } } else { soundEndFlag = 1; dac_intr.sound_reads = 0; //danko DMA_SOUND_IT_DISABLE; } } /*//danko if(!outflag && (++count >= 100000)) { outflag = 1; if(!music_control.b.mute){ HAL_I2S_DMAPause(&haudio_i2s); Delay_us(3); wm8731_left_headphone_volume_set(121 + vol); HAL_I2S_DMAResume(&haudio_i2s); } } *///danko //case PLAY_LOOP_MODE: { //danko HAL_I2S_DMAPause(&haudio_i2s); //danko Delay_us(3); //danko wm8731_left_headphone_volume_set(0); //danko HAL_I2S_DMAResume(&haudio_i2s); //danko DMA_SOUND_IT_DISABLE; raw.frame_size = media.video.width * media.video.height * sizeof(uint16_t); memcpy((void*)&fp_frame_cp, (void*)&fp_frame, sizeof(FIL)); //my_fseek(&fp_frame_cp, -raw.frame_size, SEEK_CUR); f_lseek(&fp_frame_cp, -raw.frame_size); memset((void*)frame_buffer, 0, FRAME_BUFFER_SIZE); int v; for(v = 0;v < media.video.height;v++) { //my_fread(&frame_buffer[media.video.startPosX + v * LCD_WIDTH + media.video.startPosY * LCD_WIDTH], 2, media.video.width, &fp_frame_cp); f_read(&fp_frame_cp,&frame_buffer[media.video.startPosX + v * LCD_WIDTH + media.video.startPosY * LCD_WIDTH],2* media.video.width ,NULL); } //danko ret = mjpegPause(id); outflag = 0, count = 0; /* if(ret == RET_PLAY_STOP || ret == RET_PLAY_NEXT || ret == RET_PLAY_PREV){ goto END_PROCESS; } if(ret == 1){ // ????????? ???:0 ?????? :1 ?????????????? samples /= prevSamples; getVideoSampleTime(atombuf, 0); // ?????????? getVideoSampleTime(atombuf, totalSamples); // ????????????? dac_intr.sound_reads = prevSamplesSound * soundSampleBlocks; // DAC??????????????? // videoStcoCount -= 2, soundStcoCount -= 2; ret = 0; goto CHUNK_OFFSET_HEAD; } LCDStatusStruct.waitExitKey = 1; break; */ } } EXIT_LOOP: // Per frame time duration timer (specified in the 1 / 100ms units) //danko TIM_DURATION->ARR = frameDuration * timeScaleCoeff - 1; //danko TIM_DURATION->CR1 = 0; //danko TIM_DURATION->CNT = 0; // clear counter //danko TIM3_SR_UIF_BB = 0; // clear update flag //DANKO/////////////////////////////////////TIM3_DIER_UIE_BB = 1; // set update interrupt //DANKO/////////////////////////////////////TIM3_CR1_CEN_BB = 1; // enable tim3 frames++; /* if(TIM1_SR_UIF_BB){ // ?????????? TIM1_SR_UIF_BB = 0; fps = frames - prevFrames; debug.printf("\r%c%dfps %dkbps v:%d s:%d ", fps1Hz[fpsCnt++ & 3], fps, (int)((float)(totalBytes * 8) * 0.001f), videoStcoCount, soundStcoCount); prevFrames = frames; totalBytes = 0; } */ } // AUDIO_OUT_ENABLE; if(++videoStcoCount >= video_stco.numEntry) {// || soundStcoCount >= (sound_stco.numEntry)){ goto END_PROCESS; // Play the end how much video chunk count until the last } } //FOR SAMPLES prevChunk = firstChunk; // ???firstChunk?prevChunk? prevSamples = getSampleSize(atombuf, 12, &fp_stsc); // samplesPerChunk sampleDescriptionID firstChunk = getAtomSize(&atombuf[8]); // ??firstChunk samples = firstChunk - prevChunk; // Number of samples for the next play chunk }//WHILE END_PROCESS: // ?????? // AUDIO_OUT_SHUTDOWN; printf("\r\ntotal_samples:%d video_stco_count:%d sound_stco_count:%d", totalSamples, videoStcoCount, soundStcoCount); // debug.printf("\r\ntotalRasters:%d", totalRasters); //danko HAL_I2S_DMAStop(&haudio_i2s); //danko DMA_SOUND_IT_DISABLE; HAL_Delay(10); //us // wm8731_set_active(0); //danko wm8731_left_headphone_volume_set(121 -121); // if(media.video.playJpeg){ // (void) jpeg_finish_decompress(&jdinfo); // jpeg_destroy_decompress(&jdinfo); // } EXIT_PROCESS: memset(dac_intr.buff, 0, dac_intr.bufferSize); //HAL_I2S_Transmit(&haudio_i2s, (uint16_t*)dac_intr.buff, dac_intr.bufferSize / sizeof(uint16_t), 100); BSP_AUDIO_OUT_Play((uint16_t*)dac_intr.buff, dac_intr.bufferSize / sizeof(uint16_t)); dac_intr.func = '\0'; //danko f_close(fp); //danko LCD_SetRegion(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1); //danko LCD_DrawSquare(0, 0, LCD_WIDTH, LCD_HEIGHT, BLACK); //danko if(pcf_font.ext_loaded) { //danko memcpy((void*)&pcf_font, (void*)&pcf_font_bak, sizeof(pcf_font_typedef)); //danko PCF_RENDER_FUNC_PCF(); } //danko LCDStatusStruct.waitExitKey = 0; return ret; }
int32_t collectAtoms(FILE *fp, size_t parentAtomSize, size_t child) { uint32_t i; size_t atomSize, totalAtomSize = 0; uint32_t timeScale = 0, duration = 0; FILE fp_tmp; uint8_t atombuf[512]; do{ memset(atombuf, '\0', sizeof(atombuf)); atomSize = getSampleSize(atombuf, 8, fp); // 4B Size 4B Atoma printf("\r\n"); for(i = child;i > 0;i--){ printf(" "); } printf("%s %d", (char*)&atombuf[4], atomSize); for(i = 0;i < ATOM_ITEMS;i++){ if(strncmp((char*)&atombuf[4], (char*)&atomTypeString[i][0], 4) == 0) { if(atomHasChild[i]){printf(" +"); } break; } } if(i >= ATOM_ITEMS){ // unrecognized atom if(atomSize == 0){ return -1; } goto NEXT; } memcpy((void*)&fp_tmp, (void*)fp, sizeof(FILE)); switch(i){ case MDHD: f_lseek(fp,fp->fptr+12); // skip ver/flag creationtime modificationtime timeScale = getSampleSize(atombuf, 4, fp); // time scale duration = getSampleSize(atombuf, 4, fp); // duration break; case HDLR: f_lseek(fp,fp->fptr+4); // skip flag ver read_file (fp, (uint8_t*)atombuf,4);// Component type read_file(fp, (uint8_t*)atombuf,4); // Component subtype if(!strncmp((char*)atombuf, (const char*)"soun", 4)){ media.sound.flag.process = 1; media.sound.timeScale = timeScale; media.sound.duration = duration; } if(!strncmp((char*)atombuf, (const char*)"vide", 4)){ media.video.flag.process = 1; media.video.timeScale = timeScale; media.video.duration = duration; } break; case TKHD: f_lseek(fp,fp->fptr+74); // skip till width, height data read_file(fp, (uint8_t*)atombuf,4); // width if(getAtomSize(atombuf)){ media.video.width = getAtomSize(atombuf); } read_file(fp, (uint8_t*)atombuf,4); // height if(getAtomSize(atombuf)){ media.video.height = getAtomSize(atombuf); } break; case STSD: f_lseek(fp,fp->fptr+8); // skip Reserved(6bytes)/Data Reference Index read_file(fp, (uint8_t*)atombuf,4); // next atom size read_file(fp, (uint8_t*)atombuf, getAtomSize(atombuf) - 4); if(media.video.flag.process && !media.video.flag.complete){ memset((void*)media.video.videoFmtString, '\0', sizeof(media.video.videoFmtString)); memset((void*)media.video.videoCmpString, '\0', sizeof(media.video.videoCmpString)); memcpy((void*)media.video.videoFmtString, (void*)atombuf, 4); memcpy((void*)media.video.videoCmpString, (void*)&atombuf[47], atombuf[46]); if(strncmp((char*)media.video.videoFmtString, "jpeg", 4) == 0) { media.video.playJpeg = 1; // JPEG } else { media.video.playJpeg = 0; // Uncompression } } if(media.sound.flag.process && !media.sound.flag.complete){ memcpy((void*)&media.sound.format, (void*)atombuf, sizeof(sound_format)); media.sound.format.version = (uint16_t)b2l((void*)&media.sound.format.version, sizeof(uint16_t)); media.sound.format.revision = (uint16_t)b2l((void*)&media.sound.format.revision, sizeof(media.sound.format.revision)); media.sound.format.vendor = (uint16_t)b2l((void*)&media.sound.format.vendor, sizeof(media.sound.format.vendor)); media.sound.format.numChannel = (uint16_t)b2l((void*)&media.sound.format.numChannel, sizeof(media.sound.format.numChannel)); media.sound.format.sampleSize = (uint16_t)b2l((void*)&media.sound.format.sampleSize, sizeof(media.sound.format.sampleSize)); media.sound.format.complesionID = (uint16_t)b2l((void*)&media.sound.format.complesionID, sizeof(media.sound.format.complesionID)); media.sound.format.packetSize = (uint16_t)b2l((void*)&media.sound.format.packetSize, sizeof(media.sound.format.packetSize)); media.sound.format.sampleRate = (uint16_t)b2l((void*)&media.sound.format.sampleRate, sizeof(uint16_t)); } break; case STTS: f_lseek(fp,fp->fptr+ 4); // skip flag ver if(media.video.flag.process && !media.video.flag.complete){ video_stts.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&video_stts.fp, (void*)fp, sizeof(FILE)); } if(media.sound.flag.process && !media.sound.flag.complete){ sound_stts.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&sound_stts.fp, (void*)fp, sizeof(FILE)); } break; case STSC: f_lseek(fp,fp->fptr+ 4); // skip flag ver if(media.video.flag.process && !media.video.flag.complete){ video_stsc.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&video_stsc.fp, (void*)fp, sizeof(FILE)); } if(media.sound.flag.process && !media.sound.flag.complete){ sound_stsc.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&sound_stsc.fp, (void*)fp, sizeof(FILE)); } break; case STSZ: f_lseek(fp,fp->fptr+ 4); // skip flag ver if(media.video.flag.process && !media.video.flag.complete){ video_stsz.sampleSize = getSampleSize(atombuf, 4, fp); video_stsz.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&video_stsz.fp, (void*)fp, sizeof(FILE)); } if(media.sound.flag.process && !media.sound.flag.complete){ sound_stsz.sampleSize = getSampleSize(atombuf, 4, fp); memcpy((void*)&sound_stsz.fp, (void*)fp, sizeof(FILE)); sound_stsz.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&sound_stsz.fp, (void*)fp, sizeof(FILE)); } break; case STCO: f_lseek(fp,fp->fptr+ 4); // skip flag ver if(media.video.flag.process && !media.video.flag.complete){ video_stco.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&video_stco.fp, (void*)fp, sizeof(FILE)); media.video.flag.process = 0; media.video.flag.complete = 1; } if(media.sound.flag.process && !media.sound.flag.complete){ sound_stco.numEntry = getSampleSize(atombuf, 4, fp); memcpy((void*)&sound_stco.fp, (void*)fp, sizeof(FILE)); media.sound.flag.process = 0; media.sound.flag.complete = 1; } break; default: break; } memcpy((void*)fp, (void*)&fp_tmp, sizeof(FILE)); if(i < ATOM_ITEMS && atomHasChild[i]){ // memcpy((void*)&fp_tmp, (void*)fp, sizeof(MY_FILE)); if(collectAtoms(fp, atomSize-8, child + 1) != 0){ // Re entrant return -1; } memcpy((void*)fp, (void*)&fp_tmp, sizeof(FILE)); } NEXT: f_lseek(fp,(fp->fptr+atomSize)-8); totalAtomSize += atomSize; }while(parentAtomSize > (totalAtomSize + 8)); return 0; }
__INLINE static size_t getSampleSize(void* atom_buf, int bytes, FILE *fp)// { read_file (fp, (uint8_t*)atom_buf,bytes); return getAtomSize(atom_buf); }