android::sp
// android::sp
if(spMediaExtractor->setDataSource(NULL,srcPath.c_str()) != android::OK){
return ErrCode::CodeRetEBADF;
}
源码如下:
/*
* @Descripttion:
* @version:
* @Author: chengfan
* @Date: 2022-08-10 09:30:05
* @LastEditors: chengfan
* @LastEditTime: 2022-08-16 19:45:30
*/
#include "OffSensitive.hpp"
#include "MiscUtils.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define HAS_SUR 0
#if HAS_SUR
#include
#include
#include
#endif
using namespace android;
//using android::android::ALooper;
namespace yfcf
{
OffSensitive *OffSensitive::pOffSensitive = nullptr;
OffSensitive::OffSensitive()
{
}
OffSensitive::~OffSensitive()
{
}
OffSensitive *OffSensitive::getInstance()
{
if (pOffSensitive == nullptr)
pOffSensitive = new OffSensitive();
return pOffSensitive;
}
void OffSensitive::freeInstance()
{
delete pOffSensitive;
pOffSensitive = nullptr;
}
struct AllPoints{
NuMediaExtractor* extr;
MediaCodec* vd;
MediaCodec* ad;
MediaMuxer* mux;
MediaCodec* ve;
MediaCodec* ae;
bool * shouldEnd;
bool muxStarted;
bool mvStarted;
bool maStarted;
yuv420pHandler hd;
};
static void vdFunc(void* arg);
static void adFunc(void* arg);
static void veFunc(void* arg);
static void aeFunc(void* arg);
ErrCode OffSensitive::start(string srcPath, string dstDir , string dstFileName,yuv420pHandler hd)
{
size_t srcFileSize = get_file_size(srcPath.c_str());
if( srcFileSize == 0){
return ErrCode::CodeRetEINVAL;
}
uint64_t remainSpace = check_par_remain(dstDir.c_str());
if(remainSpace <= srcFileSize ){
return ErrCode::CodeRetENOSPC;
}
bool shouldEnd = true;
android::sp
// android::sp
if(spMediaExtractor->setDataSource(NULL,srcPath.c_str()) != android::OK){
return ErrCode::CodeRetEBADF;
}
size_t trackCnt = spMediaExtractor->countTracks();
android::sp
android::AString mime;
int32_t vTrackId = -1;
sp
sp
sp
sp
int32_t aTrackId = -1;
sp
sp
sp
sp
#if HAS_SUR
sp
sp
1920, 1080, PIXEL_FORMAT_RGBA_8888);
SurfaceComposerClient::Transaction t;
t.setLayer(control, 0x10000000);
t.setLayerStack(control, 0);
t.show(control);
t.apply();
sp
#endif
for(size_t i = 0; i if(spMediaExtractor->getTrackFormat(i,&spFormat)!=OK || spFormat->findString("mime",&mime)==false ) continue; int32_t br = 0; spFormat->findInt32("bitrate",&br); int32_t prof = -1;spFormat->findInt32("profile",&prof); if (strncasecmp(mime.c_str(),"video/",6)==0){ int32_t w = 0; spFormat->findInt32("width",&w); int32_t h = 0; spFormat->findInt32("height",&h); float fr = 0.; spFormat->findFloat("frame-rate",&fr); LOGD(LOG_TAG,"w=%d h=%d fr=%f br=%d",w,h,fr,br); int32_t level = -1; spFormat->findInt32("level",&level); int32_t ifr = -1; spFormat->findInt32("frame-rate",&ifr); LOGD(LOG_TAG,"prof%d level=%d %d",prof,level,ifr); if(w==0 || h==0 ){ continue; } spVideoDecLooper = new android::ALooper(); spVideoDecLooper->setName("video_dec"); if(spVideoDecLooper->start() != OK){ LOGE(LOG_TAG,"video dec loop start err"); spVideoDecLooper.clear(); continue; } spVideoDec = MediaCodec::CreateByType(spVideoDecLooper,mime,false); if(spVideoDec.get() == nullptr){ spVideoDecLooper->stop(); spVideoDecLooper.clear(); LOGE(LOG_TAG,"create video dec err:%s",mime.c_str()); continue; } // sp #if HAS_SUR if(spVideoDec->configure(spFormat,mFlingerSurface,NULL,0) != OK){ #else if(spVideoDec->configure(spFormat,NULL,NULL,0) != OK){ #endif spVideoDecLooper->stop(); spVideoDecLooper.clear(); spVideoDec->release(); spVideoDec.clear(); LOGE(LOG_TAG,"configure video dec err"); continue; } sp veformat->setInt32("width", w); veformat->setInt32("height", h); veformat->setString("mime", "video/avc"); //OMX_COLOR_FormatYUV420Flexible veformat->setInt32("color-format", OMX_COLOR_FormatYUV420Flexible); if(br<10) br = w*h*58/10; // LOGW(LOG_TAG,"BR IS %d",br); veformat->setInt32("bitrate", br); if(fr>1.0) veformat->setFloat("frame-rate",fr); if(ifr>2) veformat->setInt32("frame-rate",ifr); // veformat->setInt32("level",level); //PROFILE_AVC_MAIN if(prof==-1) prof = 2; // veformat->setInt32("profile", prof); veformat->setInt32("i-frame-interval", 5); spVideoEncLooper = new android::ALooper(); spVideoEncLooper->setName("video_enc"); if(spVideoEncLooper->start() != OK){ spVideoDec->release(); spVideoDec.clear(); spVideoDecLooper->stop(); spVideoDecLooper.clear(); LOGE(LOG_TAG,"video enc loop start err"); spVideoEncLooper.clear(); continue; } spVideoEnc = MediaCodec::CreateByType(spVideoEncLooper,"video/avc",true); if(spVideoEnc.get() == nullptr){ spVideoEncLooper->stop(); spVideoEncLooper.clear(); LOGE(LOG_TAG,"create video enc err:%s",mime.c_str()); spVideoDecLooper->stop(); spVideoDecLooper.clear(); spVideoDec->release(); spVideoDec.clear(); continue; } if(spVideoEnc->configure(veformat,nullptr,nullptr,MediaCodec::CONFIGURE_FLAG_ENCODE) != OK){ spVideoEnc->release(); spVideoEnc.clear(); spVideoEncLooper->stop(); spVideoEncLooper.clear(); LOGE(LOG_TAG,"configure video enc err"); spVideoDec->release(); spVideoDec.clear(); spVideoDecLooper->stop(); spVideoDecLooper.clear(); continue; } if(YFUNLIKELY(spMediaExtractor->selectTrack(i)!=OK)){ LOGE(LOG_TAG,"extractor select video track err"); } vTrackId = i; shouldEnd = false; }else if(strncasecmp(mime.c_str(),"audio/",6)==0 && spAudioDecLooper.get()==nullptr){ int32_t sr = 0; spFormat->findInt32("sample-rate",&sr); int32_t mis = 0; spFormat->findInt32("max-input-size",&mis); int32_t chanelCnt= 0; spFormat->findInt32("channel-count",&chanelCnt); int32_t aacProf = -1; spFormat->findInt32("aac-profile",&aacProf); LOGD(LOG_TAG,"sr=%d br=%d mis=%d chanelCnt=%d aac_profile=%d",sr,br,mis,chanelCnt,aacProf); if(spAudioEnc.get()){ LOGW(LOG_TAG,"audio codec already inited"); continue; } spAudioDecLooper = new android::ALooper(); spAudioDecLooper->setName("audio_dec"); if(spAudioDecLooper->start() != OK){ LOGE(LOG_TAG,"Audio dec loop start err"); spAudioDecLooper.clear(); continue; } spAudioDec = MediaCodec::CreateByType(spAudioDecLooper,mime,false); if(spAudioDec.get() == nullptr){ spAudioDecLooper->stop(); spAudioDecLooper.clear(); LOGE(LOG_TAG,"create Audio dec err:%s",mime.c_str()); continue; } if(spAudioDec->configure(spFormat,nullptr,nullptr,0) != OK){ spAudioDecLooper->stop(); spAudioDecLooper.clear(); spAudioDec->release(); spAudioDec.clear(); LOGE(LOG_TAG,"configure Audio dec err"); continue; } sp aeformat->setString("mime", "audio/mp4a-latm"); if(br<10) br = 48000; aeformat->setInt32("bitrate", 125000); if(sr<100) sr = 48000; aeformat->setInt32("sample-rate",sr); if(mis<10) mis = 65541; mis = 1048576; aeformat->setInt32("max-input-size",mis); aeformat->setInt32("channel-count",1); // aeformat->setInt32("profile", prof); if(aacProf==-1) aacProf = 2; aeformat->setInt32("aac-profile", aacProf); spAudioEncLooper = new android::ALooper(); spAudioEncLooper->setName("Audio_enc"); if(spAudioEncLooper->start() != OK){ spAudioDecLooper->stop(); spAudioDecLooper.clear(); spAudioDec->release(); spAudioDec.clear(); LOGE(LOG_TAG,"Audio enc loop start err"); spAudioEncLooper.clear(); continue; } spAudioEnc = MediaCodec::CreateByType(spAudioEncLooper,"audio/mp4a-latm",true); if(spAudioEnc.get() == nullptr){ spAudioEncLooper->stop(); spAudioEncLooper.clear(); LOGE(LOG_TAG,"create Audio enc err:%s",mime.c_str()); spAudioDecLooper->stop(); spAudioDecLooper.clear(); spAudioDec->release(); spAudioDec.clear(); continue; } if(spAudioEnc->configure(aeformat,NULL,NULL,MediaCodec::CONFIGURE_FLAG_ENCODE) != OK){ spAudioEncLooper->stop(); spAudioEncLooper.clear(); spAudioEnc->release(); spAudioEnc.clear(); LOGE(LOG_TAG,"configure Audio enc err"); spAudioDecLooper->stop(); spAudioDecLooper.clear(); spAudioDec->release(); spAudioDec.clear(); continue; } if(YFUNLIKELY(spMediaExtractor->selectTrack(i)!=OK)){ LOGE(LOG_TAG,"extractor select Audio track err"); } aTrackId = i; shouldEnd = false; }
} if(shouldEnd){ return ErrCode::CodeRetEBADF; } string dstFileFull = dstDir + dstFileName; int outFd = open( dstFileFull.c_str(), O_CREAT|O_CLOEXEC|O_TRUNC|O_RDWR,0666); if(outFd == -1){ LOGE(LOG_TAG,"open file err %s %s",dstFileFull.c_str(),strerror(errno)); } sp if(vTrackId>=0){ if(spVideoDec->start()!=OK) LOGE(LOG_TAG,"video dec start err,should never happen"); } if(aTrackId>=0){ if(spAudioDec->start()!=OK) LOGE(LOG_TAG,"audio dec start err,should never happen"); } AllPoints arg = {spMediaExtractor.get(),spVideoDec.get(),spAudioDec.get(),spMediaMux.get(),spVideoEnc.get(),spAudioEnc.get(),&shouldEnd,false,false,false,hd}; std::thread vdTid(vdFunc,&arg); std::thread adTid(adFunc,&arg); size_t avTrackId = -1011; size_t buffIndex; status_t tmp; size_t sampSize; int64_t pts; AString err_str; sp #if 0 Vector spVideoDec->getInputBuffers(&vdBufs); Vector spVideoDec->getInputBuffers(&adBufs); #endif while (!shouldEnd) { tmp = spMediaExtractor->getSampleTrackIndex(&avTrackId); // LOGD(LOG_TAG,"avTrackId is %" PRIuFAST32,avTrackId); if(tmp == -1011){ shouldEnd = true; LOGI(LOG_TAG,"EXTRACTOR end"); break; } if(spMediaExtractor->getSampleSize(&sampSize) != OK || spMediaExtractor->getSampleTime(&pts)!= OK){ LOGE(LOG_TAG,"this should never happen"); } if(sampSize<=0){ shouldEnd = true; LOGI(LOG_TAG,"EXTRACTOR end2"); break; } if(avTrackId == vTrackId){ while( (tmp = spVideoDec->dequeueInputBuffer(&buffIndex,70000))!=OK) { static uint32_t cnt = 0; cnt++; if(tmp!=-11) cnt = 11; if(cnt>=10){ LOGI(LOG_TAG,"VD dequeue ibuff err %d",tmp); cnt = 0; } } sp spVideoDec->getInputBuffer(buffIndex,&spMediaCodecBuf); // spMediaCodecBuf = vdBufs.itemAt(buffIndex); spAbuf = new ABuffer(spMediaCodecBuf->base(), spMediaCodecBuf->capacity()); tmp =spMediaExtractor->readSampleData(spAbuf); if(tmp != OK){ LOGI(LOG_TAG,"V readSampleData err %" PRId32,tmp); continue; } spMediaCodecBuf->setRange(spAbuf->offset(), spAbuf->size()); tmp = spVideoDec->queueInputBuffer(buffIndex,spAbuf->offset(),spAbuf->size(),pts,0,&err_str); if(tmp!=OK){ LOGE(LOG_TAG,"V dec queue ibuff err:%d %s",tmp,err_str.c_str()); } spMediaExtractor->advance(); }else if(avTrackId == aTrackId){ while( (tmp = spAudioDec->dequeueInputBuffer(&buffIndex,50000))!= OK){ LOGI(LOG_TAG,"aD dequeue ibuff err %" PRId32,tmp); continue; } sp while ( (tmp = spAudioDec->getInputBuffer(buffIndex,&spMediaCodecBuf))!=OK) { LOGW(LOG_TAG,"a err %d bidx=%" PRIuFAST32,tmp,buffIndex); } spAbuf = new ABuffer(spMediaCodecBuf->base(), spMediaCodecBuf->capacity()); tmp =spMediaExtractor->readSampleData(spAbuf); if(tmp != OK){ LOGI(LOG_TAG,"a readSampleData err %" PRId32,tmp); continue; } tmp = spAudioDec->queueInputBuffer(buffIndex,0,sampSize,pts,0,&err_str); if(tmp!=OK){ LOGE(LOG_TAG,"a dec queue ibuff err:%d %s",tmp,err_str.c_str()); } spMediaExtractor->advance(); } } vdTid.join(); adTid.join(); spMediaMux->stop(); if(outFd!=-1) close(outFd); spVideoDec->stop(); spVideoDec->release(); spVideoDecLooper->stop(); spVideoEnc->stop(); spVideoEnc->release(); spVideoEncLooper->stop();
spAudioDec->stop(); spAudioDec->release(); spAudioDecLooper->stop(); spAudioEnc->stop(); spAudioEnc->release(); spAudioEncLooper->stop(); #if HAS_SUR mFlingerSurface.clear(); control.clear(); mSession.clear(); #endif LOGI(LOG_TAG,"off-sensitive end"); return ErrCode::CodeRetOK; } void vdFunc(void* arg){ AllPoints* all = (AllPoints*)arg; all->ve->start(); size_t bufIdx; size_t offset = 0; size_t sampSize; int64_t pts; uint32_t oFlags; size_t oBufIdx; status_t tmp; sp sp AString err_str; bool* shouldEnd = all->shouldEnd; std::thread veTid(veFunc,arg); while(*shouldEnd == false){ oFlags = 0; tmp = all->vd->dequeueOutputBuffer(&bufIdx,&offset,&sampSize,&pts,&oFlags,20000); if((tmp!=OK && tmp!=-11)||oFlags>1 ){ LOGD(LOG_TAG,"VD de obuf tmp=%d flag %d index=%" PRIuFAST32 ,tmp,oFlags,bufIdx); } if(tmp == -1012){ sp all->vd->getOutputFormat(&format); int32_t cf = -1; format->findInt32("color-format",&cf); LOGW(LOG_TAG,"VD COlor format is %d",cf); } if(tmp!=OK) continue; if(oFlags&MediaCodec::BUFFER_FLAG_EOS){ *shouldEnd = true; break; } if(bufIdx>=0){ all->vd->getOutputBuffer(bufIdx,&spMcb); if(all->hd) { all->hd(spMcb->data(),spMcb->size()); } while( (tmp = all->ve->dequeueInputBuffer(&oBufIdx,50000) ) !=OK){ LOGI(LOG_TAG,"VE de ibuf err %" PRId32,tmp); } all->ve->getInputBuffer(oBufIdx,&spMcbi); spMcbi->setRange(spMcb->offset(),spMcb->size()); memcpy(spMcbi->data(),spMcb->data(),spMcb->size()); tmp =all->ve->queueInputBuffer(oBufIdx,0,sampSize,pts,0,&err_str); if(tmp!=OK){ LOGW(LOG_TAG,"ve queue ibuf err %s %" PRId32,err_str.c_str(),tmp); } all->vd->releaseOutputBuffer(bufIdx); } } all->vd->flush(); LOGI(LOG_TAG,"vd end"); veTid.join(); } static uint64_t avTs[2] = {0,0}; void veFunc(void* arg){ AllPoints* all = (AllPoints*)arg; size_t bufIdx; size_t offset = 0; size_t sampSize; int64_t pts; uint32_t oFlags; size_t oBufIdx; status_t tmp; sp AString err_str; sp bool* shouldEnd = all->shouldEnd; size_t vTrackIdE = -1; sp while (*shouldEnd == false) { oFlags = 0; tmp = all->ve->dequeueOutputBuffer(&bufIdx,&offset,&sampSize,&pts,&oFlags,20000); if((tmp!=OK && tmp!=-11)||oFlags >1 ){ LOGD(LOG_TAG,"Ve de obuf tmp=%d flag %d index=%" PRIuFAST32 ,tmp,oFlags,bufIdx); } switch (tmp) { case OK:{ all->ve->getOutputBuffer(bufIdx,&spMcb); spAbuf = new ABuffer(spMcb->data(),spMcb->size()); if(avTs[0]==0){ avTs[0] = bag_get_boot_time(); LOGW(LOG_TAG,"vpts=%" PRId64 ,pts); } if(all->muxStarted) all->mux->writeSampleData(spAbuf,vTrackIdE,pts,oFlags); all->ve->releaseOutputBuffer(bufIdx); } break; case INFO_FORMAT_CHANGED:{ all->ve->getOutputFormat(&oFormat); vTrackIdE = all->mux->addTrack(oFormat); //toDo lock all->mvStarted = true; if(all->maStarted){ all->mux->start(); all->muxStarted = true; } } break; default: break; } if(oFlags&MediaCodec::BUFFER_FLAG_EOS ){ *shouldEnd = true; break; } } all->ve->flush(); LOGI(LOG_TAG,"ve end"); }
void adFunc(void* arg){ AllPoints* all = (AllPoints*)arg; all->ae->start(); size_t bufIdx; size_t offset = 0; size_t sampSize; int64_t pts; uint32_t oFlags; size_t oBufIdx; status_t tmp; sp sp AString err_str; bool* shouldEnd = all->shouldEnd; std::thread aeTid(aeFunc,arg); while(*shouldEnd == false){ oFlags = 0; tmp = all->ad->dequeueOutputBuffer(&bufIdx,&offset,&sampSize,&pts,&oFlags,20000); if((tmp!=OK && tmp!=-11)||oFlags>1 ){ LOGD(LOG_TAG,"aD de obuf flag %d tmp=%d index=%" PRIuFAST32 ,oFlags,tmp,bufIdx); } if(oFlags&MediaCodec::BUFFER_FLAG_EOS ){ *shouldEnd = true; break; } if(tmp == OK){ all->ad->getOutputBuffer(bufIdx,&spMcb); while( (tmp = all->ae->dequeueInputBuffer(&oBufIdx,50000) ) !=OK){ LOGI(LOG_TAG,"aE de ibuf err %" PRId32,tmp); } all->ae->getInputBuffer(oBufIdx,&spMcbi); // LOGD(LOG_TAG,"off=%" PRIuFAST32 "cap=%" PRIuFAST32,spMcb->offset(),spMcb->capacity()); spMcbi->setRange(spMcb->offset(),spMcb->size()); memcpy(spMcbi->data(),spMcb->data(),spMcb->size()); tmp =all->ae->queueInputBuffer(oBufIdx,0,sampSize,pts,0,&err_str); if(tmp!=OK){ LOGW(LOG_TAG,"ae queue ibuf err %s %" PRId32,err_str.c_str(),tmp); } all->ad->releaseOutputBuffer(bufIdx); } } all->ad->flush(); LOGI(LOG_TAG,"ad end"); aeTid.join(); } struct ABuffInfo{ uint8_t* data; size_t dl; uint32_t oFlags; int64_t pts; }; void aeFunc(void* arg){ AllPoints* all = (AllPoints*)arg; size_t bufIdx; size_t offset = 0; size_t sampSize; int64_t pts; uint32_t oFlags; size_t oBufIdx; status_t tmp; sp AString err_str; sp bool* shouldEnd = all->shouldEnd; size_t aTrackIdE = -1; sp Vector bufs.clear(); int ccc=0; while (*shouldEnd == false) { oFlags = 0; tmp = all->ae->dequeueOutputBuffer(&bufIdx,&offset,&sampSize,&pts,&oFlags,20000); if((tmp!=OK && tmp!=-11)||oFlags>1 ){ LOGD(LOG_TAG,"ae de obuf tmp=%d flag %d index=%" PRIuFAST32 ,tmp,oFlags,bufIdx); } switch (tmp) { case OK:{ if(oFlags&MediaCodec::BUFFER_FLAG_EOS ){ *shouldEnd = true; break; }else if(oFlags&MediaCodec::BUFFER_FLAG_CODECCONFIG){
} all->ae->getOutputBuffer(bufIdx,&spMcb); spAbuf = new ABuffer(spMcb->data(),sampSize); static uint64_t loss = 0; static int64_t ps = 0; #if 1 ABuffInfo* bi = new ABuffInfo; bi->data = (uint8_t*)malloc(sampSize); memcpy(bi->data,spMcb->data(),sampSize); bi->dl = sampSize; bi->oFlags = oFlags; bi->pts = pts; bufs.add(bi); ccc++; #endif if(all->muxStarted){ #if 1 for(size_t i =0 ;i sp tmp = all->mux->writeSampleData(ab,aTrackIdE,bufs.editItemAt(i)->pts,bufs.editItemAt(i)->oFlags); if(tmp!=OK || bufs.editItemAt(i)->oFlags){ LOGE(LOG_TAG,"tmp-=%d %" PRIu32,tmp,bufs.editItemAt(i)->oFlags); } free(bufs.editItemAt(i)->data); delete bufs.editItemAt(i); bufs.removeAt(i); break; } #endif if(avTs[1]==0){ avTs[1] = bag_get_boot_time(); LOGW(LOG_TAG,"av %" PRIu64 " %" PRIu64,avTs[1],avTs[0]); LOGW(LOG_TAG,"TS %" PRId64 " %" PRId64 " %" PRIu64,ps,pts,loss); ps = pts; } // tmp = all->mux->writeSampleData(spAbuf,aTrackIdE,pts,oFlags); } else{ if(ps==0) ps = pts; loss+=sampSize; } all->ae->releaseOutputBuffer(bufIdx); } break; case INFO_FORMAT_CHANGED:{ all->ae->getOutputFormat(&oFormat); aTrackIdE = all->mux->addTrack(oFormat); //toDo lock all->maStarted = true; if(all->mvStarted){ all->mux->start(); all->muxStarted = true; } } break; default: break; } } all->ae->flush(); LOGI(LOG_TAG,"ae end"); } }