/**
    \fn switchToSegment
    \brief Switch to the segment given as argument

*/
bool        ADM_Composer::switchToSegment(uint32_t s,bool dontdecode)
{
    if(s+1>_segments.getNbSegments())
    {
        ADM_warning("Cannot switch to segment:%"PRIu32"\n",s);
        return false;
    }
    _SEGMENT *seg=_segments.getSegment(s);
    ADM_assert(seg);
    ADM_info("Trying to switch to seg %"PRIu32" with startTime in reference pic= %"PRIu32" ms\n",s,seg->_refStartTimeUs/1000);
        // If the refStartTime is 0, it is the first image
        // But the fist image might not be = 0
      _VIDEOS *vid=_segments.getRefVideo(seg->_reference);
      vidHeader 	*demuxer=vid->_aviheader;  
      ADM_assert(vid);
      uint64_t from=seg->_refStartTimeUs;
      uint64_t pts,dts;

      if(!from) from=vid->firstFramePts;

    
    if(false==seektoTime(seg->_reference,from,dontdecode))
    {
            ADM_warning("Cannot seek to beginning of segment %"PRIu32" at  %"PRIu64" ms\n",s,from/1000);
            return false;
    }
    _currentSegment=s;
    ADM_info("Switched ok to segment %"PRIu32" (dontdecode=%d)\n",s,dontdecode);
    return true;
}
bool ADM_Composer::addToUndoQueue(void)
{
    // truncate the dead branch first if we add a new element to the undo queue after _cnt-1 undo steps
    if(_cnt>1 && undoQueue.size()>1)
    {
        for(uint32_t i=0;i<_cnt;i++)
        {
            undoQueue.pop_back();
        }
        ADM_info("Deleted last %d elements from the undo queue\n",_cnt);
    }
    // now populate the new element...
    undoQueueElem rec;
    uint64_t a=getMarkerAPts();
    uint64_t b=getMarkerBPts();
    rec.segm=_segments.getSegments();
    rec.markerA=a;
    rec.markerB=b;
    // ...do some housekeeping...
    uint32_t m=maxUndoSteps;
    if(m<10) m=10; // less than 10 undo steps is a bad idea, ignore the limit then
    uint32_t nb=undoQueue.size();
    if(nb>m)
    {
        // erase the oldest records if the limit is exceeded and create space for a new one
        undoQueue.erase(undoQueue.begin(),undoQueue.begin()+nb-m+1);
    }
    // ...and store the new element in the queue
    undoQueue.push_back(rec);
    ADM_info("The undo queue has now %d element(s)\n",undoQueue.size());
    _cnt=0; // redo should not be available after a new undo-able action has been performed
    return true;
}
/**
    \fn    setupAudio
    \brief create the audio streams we will use (copy/process)
*/
bool admSaver::setupAudio()
{
    bool r=true;
    ADM_info("Setting up %d audio track(s)\n",nbAudioTracks);
    for(int i=0;i<nbAudioTracks;i++)
    {
            EditableAudioTrack *ed=video_body->getEditableAudioTrackAt(i);
            ADM_audioStream *access=NULL;
            if(ed->encoderIndex) // encode
            {
                // Access..
                ADM_info("[audioTrack %d] Creating audio encoding stream, starttime %s(encoding with encoder=%d)\n",i,ADM_us2plain(startAudioTime),ed->encoderIndex);
                access=audioCreateEncodingStream(ed,muxer->useGlobalHeader(),startAudioTime); // FIXME LEAK FIXME 
            }else // copy mode...
            {
                ADM_info("[audioTrack %d] Creating audio encoding stream, starttime %s(copy)\n",i,ADM_us2plain(startAudioTime));
                int32_t shift=0;
                if(ed->audioEncodingConfig.shiftEnabled)
                {
                    shift=ed->audioEncodingConfig.shiftInMs;
                    ADM_info("Using shift of %d ms\n",(int)shift);
                }
                access=audioCreateCopyStream(startAudioTime,shift,ed->edTrack,!muxer->canDealWithTimeStamps());
            }
            if(!access)
            {
                    GUI_Error_HIG("Audio","Cannot setup audio encoder, make sure your stream is compatible with audio encoder (number of channels, bitrate, format)");
                    return false;
            }
            audioAccess[i]=access;

    }
    return r;
}
/**
    \fn GoToIntraTime
    \brief Go to an intra at time time (exact)
    \return true on success, false on error
*/
bool        ADM_Composer::goToIntraTimeVideo(uint64_t time)
{
    uint32_t frame;
    if(false==GoToIntraTime_noDecoding(time,&frame))
    {
        ADM_warning("Seek failed.\n");
        return false;
    }
    _SEGMENT *seg=_segments.getSegment(_currentSegment);
    // Ok, we have switched to a new segment
    // Flush the cache
    _VIDEOS *vid= _segments.getRefVideo(seg->_reference);
    if(false== DecodePictureUpToIntra(seg->_reference,frame))
    {
        return false;
    }
    // Get the last decoded PTS and it is our current PTS
    uint64_t newPts=vid->lastDecodedPts+seg->_startTimeUs;
    newPts-=seg->_refStartTimeUs;
    SET_CURRENT_PTS(newPts);
#if 0
    ADM_info("decodec DTS=%"PRIu64" ms\n",vid->lastDecodedPts/1000);
    ADM_info("startTime DTS=%"PRIu64" ms\n",seg->_startTimeUs/1000);
    ADM_info("refstart DTS=%"PRIu64" ms\n",seg->_refStartTimeUs/1000);
    ADM_info("Current DTS=%"PRIu64" ms\n",_currentPts/1000);
#endif
    return true;
}
/**
    \fn stopThread
*/
bool ADM_threadQueue::stopThread(void)
{
        ADM_info("Destroying threadQueue\n");
        mutex->lock();

        if(threadState==RunStateRunning)
        {
            threadState=RunStateStopOrder;

            if(cond->iswaiting())
            {
                cond->wakeup();
            }

            mutex->unlock();

			int clockDown=10;

            while(threadState!=RunStateStopped && clockDown)
            {
                ADM_usleep(50*1000);
                clockDown--;
            };

            ADM_info("Thread stopped, continuing dtor\n");
        }else
        {
                mutex->unlock();
        }
        return true;
}
ADM_threadQueue::~ADM_threadQueue()
{
    ADM_info("Killing audio thread and son\n");
    // ask the thread to stop

    if(started)
    {
        mutex->lock();
        if(threadState==RunStateRunning)
        {
            ADM_info("Asking the thread to stop\n");
            threadState=RunStateStopOrder;
            if(cond->iswaiting())
            {
                cond->wakeup();
            }
            mutex->unlock();
            int count=100;
            while(count)
            {
                if(threadState==RunStateStopped) break;
                ADM_usleep(1000*100); // Slep 100 ms
            }
        }else mutex->unlock();
        void *ret;
        pthread_join(myThread, &ret);
    }
    
    if(cond) delete cond;
    if(mutex) delete mutex;
    cond=NULL;
    mutex=NULL;
}
/**
    \fn startNewRiffIfNeeded
*/
bool aviIndexOdml::startNewRiffIfNeeded(int trackNo,int len)
{
    bool breakNeeded=false;

    // Case 1: we exceed riff boundary (4 GB)
        uint64_t currentPosition=LMovie->Tell();
        uint64_t start=_masterList->TellBegin();
        uint64_t riffSize=currentPosition-start;
        uint64_t limit=((1LL<<31)-10*(1LL<<20)); // 2GB per riff chunk
        riffSize+=len;
        if(!riffCount) // take into account legacy index
        {
            for(int i=0;i<1+nbAudioTrack;i++)
                limit-=4*4*indexes[i].listOfChunks.size();
        }
        if(riffSize> limit)
        {
            ADM_info("Riff is now %" PRIu64" bytes, break needed\n",riffSize);
            breakNeeded=true;
        }

    // Case 2 : the current index is full
        int available=(AVI_REGULAR_INDEX_CHUNK_SIZE-64)/8; // nb index entry
        if(indexes[trackNo].listOfChunks.size()>=available)
        {
            ADM_info("Index for track %d is full\n",trackNo);
            breakNeeded=true;
        }
        if(breakNeeded)
            startNewRiff();
        return true;
}
Example #8
0
void qtRegisterDialog(QWidget *dialog)
{
    if (widgetStack.count())
    {
        Qt::WindowFlags flags = dialog->windowFlags();
        bool reparent = false;
        bool isDialog = false;
        if (dialog->parentWidget() != widgetStack.top())
            reparent = true;
        if (flags & Qt::Dialog)
            isDialog = true;
#if defined(__APPLE__) && QT_VERSION == QT_VERSION_CHECK(5,10,1)
        if (reparent || isDialog)
        {
            ADM_info("Working around Qt bug introduced in 5.10.1 resulting in non-resizable dialogs with Cocoa\n");
            dialog->setWindowFlag(Qt::Dialog, false);
            dialog->setParent(widgetStack.top(), Qt::Window);
            dialog->setWindowModality(Qt::ApplicationModal);
            dialog->show();
        }
#else
        if (reparent || !isDialog)
        {
            ADM_info("reparenting widget %s\n",dialog->objectName().toUtf8().constData());
            dialog->setParent(widgetStack.top(), Qt::Dialog);
            dialog->show(); // reparenting makes the widget invisible
        }
#endif
    }
    widgetStack.push(dialog);
}
/**
    \fn detectTs
    \brief returns true if the file seems to be mpeg PS

*/
bool detectTs(const char *file)
{
    uint8_t buffer[PROBE_SIZE];
    uint32_t bufferSize;
    uint32_t nbPacket,nbMatch=0;

    FILE *f=ADM_fopen(file,"rb");
    if(!f) return false;
    bufferSize=fread(buffer,1,PROBE_SIZE,f);
    fclose(f);
    // Do a simple check by checking we have 0x47....0x47 several time in a raw
    if(true==checkMarker(buffer,bufferSize,TS_PACKET_LEN))
    {
        ADM_info("[TS Demuxer] 188 bytes packet detected\n");
        return true;
    }
    // Do a simple check by checking we have 0x47....0x47 several time in a raw
    if(true==checkMarker(buffer,bufferSize,TS_PACKET_LEN+4))
    {
        ADM_info("[TS Demuxer] 192 bytes packet detected\n");
        return true;
    }
    ADM_info("[TS Demuxer] Not a TS file\n");
    return false;
}
Example #10
0
uint8_t asfHeader::open(const char *name)
{
  _fd=ADM_fopen(name,"rb");
  if(!_fd)
  {
    GUI_Error_HIG("File Error.","Cannot open file\n");
    return 0; 
  }
  myName=ADM_strdup(name);
  if(!getHeaders())
  {
    return 0; 
  }
  ADM_info("Stream Video: index=%d, sid=%d\n",(int)_videoIndex,(int)_videoStreamId);
  for(int i=0;i<_nbAudioTrack;i++)
    ADM_info("Stream Audio: index=%d, sid=%d\n",
                (int)_allAudioTracks[i].streamIndex,(int)_allAudioTracks[i].streamIndex);
  buildIndex();
  fseeko(_fd,_dataStartOffset,SEEK_SET);
  _packet=new asfPacket(_fd,_nbPackets,_packetSize,&readQueue,&storageQueue,_dataStartOffset);
  curSeq=1;
  for(int i=0;i<_nbAudioTrack;i++)
  {
        _audioAccess[i]=new asfAudioAccess(this,i);
        _audioStreams[i]=ADM_audioCreateStream(&(_allAudioTracks[i].wavHeader), _audioAccess[i]);
  }
  if(!nbImage)
    {
        ADM_error("No image found \n");
        return 0;
    }
  return 1;
}
Example #11
0
/**
 * \fn compute the minimum us delta = maximum fps
 * \brief average fps is not good enough, it might be too high
 * @return 
 */
bool MP4Header::refineFps(void)
{
    int n=VDEO.nbIndex;
    uint64_t minDelta=60*1000*1000;
    for(int i=0;i<n-1;i++)
    {
        MP4Index *dex=&(_tracks[0].index[i]);
        MP4Index *next=&(_tracks[0].index[i+1]);
        if(dex->dts==ADM_NO_PTS) continue;
        if(next->dts==ADM_NO_PTS) continue;
        uint64_t delta=next->dts-dex->dts;
        if(delta<minDelta) minDelta=delta;
    }
    if(minDelta>1000)
    {
        double f=1000000./(double)minDelta;
        f*=1000.;
        ADM_info("MinDelta=%d us\n",(int)minDelta);
        ADM_info("Computed fps1000=%d\n",(int)f);
        uint32_t fps1000=floor(f+0.49);
        if(fps1000>  _videostream.dwRate)
        {
            ADM_info("Adjusting fps, the computed is higher than average, dropped frames ?\n");
           _videostream.dwRate=fps1000;
           _mainaviheader.dwMicroSecPerFrame=ADM_UsecFromFps1000(_videostream.dwRate);
        }
    }
    
}
bool AUDMEncoder_DcaEnc::initialize (void)
{
  int chan_config=0;
  switch(wavheader.channels)
  {
    case 1: chan_config=DCAENC_CHANNELS_MONO;break;
    case 2: chan_config=DCAENC_CHANNELS_STEREO;break;
    case 6: chan_config=DCAENC_CHANNELS_3FRONT_2REAR_1OV;break;
    case 5: chan_config=DCAENC_CHANNELS_3FRONT_2REAR;break;
    default:
         ADM_warning("Unsupported channel configuration \n");
         break;
  }
  wavheader.byterate=(config.bitrate*1000)>>3;
  ADM_info("Starting dcaenc with channels=%d, bitrate=%d\n",wavheader.channels,config.bitrate);
  context=dcaenc_create(wavheader.frequency,chan_config,config.bitrate*1000,DCAENC_FLAG_BIGENDIAN   );
  
  if(!context)
  {
      ADM_warning("Cannot create dcaenc context   \n");
      return false;
  }
  inputSize=dcaenc_input_size(context);
  outputSize=dcaenc_output_size(context);
  ADM_info("Converting %d samples to %d bytes\n",inputSize,outputSize);
  return true;
}
Example #13
0
/**
    \fn convertLinearTimeToSeg
    \brief convert linear time to a segment+ offset in the segment
*/
bool        ADM_EditorSegment::convertLinearTimeToSeg(  uint64_t frameTime, uint32_t *seg, uint64_t *segTime)
{
    if(!frameTime && segments.size()) // pick the first one
    {
        ADM_info("Frame time=0, taking first segment \n");
        *seg=0;
        *segTime=0; // ??
        return true;
    }
    for(int i=0;i<segments.size();i++)
    {
        if(segments[i]._startTimeUs<=frameTime && segments[i]._startTimeUs+segments[i]._durationUs>frameTime)
        {
            *seg=i;
            *segTime=frameTime-segments[i]._startTimeUs;
            return true;
        }
    }
    int max=segments.size();
    if(max)
    {
        _SEGMENT *last=&(segments[max-1]);
        if(frameTime==last->_startTimeUs+last->_durationUs)
        {
            ADM_info("End of last segment\n");
            *seg=max-1;
            *segTime=frameTime-last->_startTimeUs;
            return true;
        }
    }
    ADM_warning("Cannot find segment matching time %"PRIu64"ms \n",frameTime/1000);
    dump();
    return false;
}
/**
    \fn resetVdpau
*/
bool vdpauVideoFilterDeint::setupVdpau(void)
{
    scaler=NULL;
    secondField=false;
    nextFrame=0;
    if(!admVdpau::isOperationnal())
    {
        ADM_warning("Vdpau not operationnal\n");
        return false;
    }   
    if(VDP_STATUS_OK!=admVdpau::outputSurfaceCreate(VDP_RGBA_FORMAT_B8G8R8A8,
                        info.width,info.height,&outputSurface)) 
    {
        ADM_error("Cannot create outputSurface0\n");
        return false;
    }
    for(int i=0;i<ADM_NB_SURFACES;i++) surfacePool[i]=VDP_INVALID_HANDLE;
    for(int i=0;i<ADM_NB_SURFACES;i++)
    {
        if(VDP_STATUS_OK!=admVdpau::surfaceCreate(   previousFilter->getInfo()->width,
                                                    previousFilter->getInfo()->height,
                                                    &(surfacePool[i]))) 
        {
            ADM_error("Cannot create input Surface %d\n",i);
            goto badInit;
        }
        aprintf("Created surface %d\n",(int)surfacePool[i]);
    }
    // allocate our (dummy) images
    for(int i=0;i<3;i++)
        xslots[i].image=new ADMImageDefault( previousFilter->getInfo()->width, 
                                            previousFilter->getInfo()->height);
                                            
    if(VDP_STATUS_OK!=admVdpau::mixerCreate(previousFilter->getInfo()->width,
                                            previousFilter->getInfo()->height,&mixer,true)) 
    {
        ADM_error("Cannot create mixer\n");
        goto badInit;
    } 
    tempBuffer=new uint8_t[info.width*info.height*4];
    scaler=new ADMColorScalerSimple( info.width,info.height, ADM_COLOR_BGR32A,ADM_COLOR_YV12);

    freeSurface.clear();
    for(int i=0;i<ADM_NB_SURFACES;i++)  
            freeSurface.push_back(surfacePool[i]);

    
    ADM_info("VDPAU setup ok\n");
    if(initGl()==false)
    {
        ADM_error("Cannot setup openGL\n");
        goto badInit;
    }
    ADM_info("VDPAU setup ok\n");
    return true;
badInit:
    cleanupVdpau();
    passThrough=true;
    return false;
}
void loadTranslator(void)
{
	
        char *lang=NULL;
        bool autoSelect=true;
        if(prefs->get(DEFAULT_LANGUAGE,&lang))
        {
            if(lang && strlen(lang)>0 && strcmp(lang,"auto"))
                autoSelect=false;
        }
        if(autoSelect)
        {
            ADM_info("Using system language\n");
            lang=ADM_strdup(QLocale::system().name().toUtf8().constData());
        }else
        {
            ADM_info("Language forced \n");
        }
        ADM_info("Initializing language %s\n",lang);
#ifdef __APPLE__
	QString appdir = QCoreApplication::applicationDirPath() + "/../share/avidemux6/i18n/";
                
#elif defined(_WIN32)
	QString appdir = QCoreApplication::applicationDirPath() + "/i18n/";
#else
	QString appdir = ADM_getInstallRelativePath("share","avidemux6","i18n");
#endif
        QString languageFile=QString(lang);
    int nbLoaded=0;
	nbLoaded+=loadTranslation(&qtTranslator, appdir + "qt_" + languageFile);
	nbLoaded+=loadTranslation(&avidemuxTranslator, appdir + "avidemux_" + languageFile);
	translatorLoaded = true;
    if(!nbLoaded) // Nothing to translate..
        return;
    ADM_info("Updating translations...\n");
	// Re-translate existing map (to take care of global strings already allocated)
        if(!map)
            map = new QMap<QString, char*>;
	QMapIterator<QString, char*> mapIterator(*map);

	while (mapIterator.hasNext())
	{
		mapIterator.next();

		QByteArray translatedMessage = QApplication::translate("", mapIterator.key().toAscii().constData()).toUtf8();
		char *buffer = mapIterator.value();
		int copyLength = translatedMessage.length() + 1;

		if (copyLength > MAX_UNLOADED_MSG_LENGTH + 1)
		{
			copyLength = MAX_UNLOADED_MSG_LENGTH;
			buffer[MAX_UNLOADED_MSG_LENGTH] = '\0';
		}

		memcpy(buffer, translatedMessage.constData(), copyLength);
	}

	ADM_info("[Locale] Test: &Edit -> %s\n\n", HIDE_STRING_FROM_QT("MainWindow", "&Edit").toUtf8().data());
        
}
Example #16
0
bool  aviIndexOdml::writeIndex()
{
            if(!riffCount)
                prepareLegacyIndex();
            // super index needed ?
            ADM_info("Writting openDml chunk\n");
            writeOdmlChunk();
            ADM_info("Writting type 2 Avi index\n");
            for(int i=0;i<1+nbAudioTrack;i++)
                writeRegularIndex(i);
            ADM_info("Writting type 2 Avi SuperIndex\n");
            writeSuperIndex();
            LMovie->End();
            if(!riffCount)
            {
                ADM_info("Writting legacy index\n");
                writeLegacyIndex();
            }
            delete LMovie;  
            LMovie=NULL;

            _masterList->End();
            delete _masterList;
            _masterList=NULL;
            return true;
}
/**
 * 
 * @param avctx
 * @param fmt
 * @param outputFormat
 * @return 
 */
bool           ADM_hwAccelEntryLibVA::canSupportThis(struct AVCodecContext *avctx,  const enum AVPixelFormat *fmt,enum AVPixelFormat &outputFormat)
{
    bool enabled=false;
    prefs->get(FEATURES_LIBVA,&enabled);
    if(!enabled)
    {
        ADM_info("LibVA not enabled\n");
        return false;
    }
    enum AVPixelFormat ofmt=ADM_LIBVA_getFormat(avctx,fmt);
    if(ofmt==AV_PIX_FMT_NONE)
        return false;
    outputFormat=ofmt;
    ADM_info("This is maybe supported by LIBVA\n");
    VAProfile profile=VAProfileNone;
    switch(avctx->codec_id)
    {
       case AV_CODEC_ID_H264: profile= VAProfileH264High;break;
#ifdef LIBVA_HEVC_DEC       
       case AV_CODEC_ID_H265: profile= VAProfileHEVCMain;break;;
#endif       
       case AV_CODEC_ID_VC1: profile= VAProfileVC1Advanced;break;
#ifdef LIBVA_VP9_DEC
       case AV_CODEC_ID_VP9: profile= VAProfileVP9Profile3;break;
#endif
       default:
           return false;
    }
    if(!admLibVA::supported(profile))
    {
        ADM_warning("Not supported by libVA\n");
        return false;
    }
    return true;
}
Example #18
0
/**
    \fn removeChunk
    \brief
*/
bool        ADM_EditorSegment::removeChunk(uint64_t from, uint64_t to)
{
    uint32_t startSeg,endSeg;
    uint64_t startOffset,endOffset;

    ADM_info("Cutting from %"PRIu64" to %"PRIu64" ms\n",from/1000,to/1000);
    dump();
    if(false==convertLinearTimeToSeg( from,&startSeg,&startOffset))
    {
        ADM_warning("Cannot get starting point (%"PRIu64" ms\n",from/1000);
        return false;
    }
    if(false==convertLinearTimeToSeg( to,&endSeg,&endOffset))
    {
        ADM_warning("Cannot get starting point (%"PRIu64" ms\n",from/1000);
        return false;
    }

    ADM_info("Start, seg %"PRIu32" Offset :%"PRIu64" ms\n",startSeg,startOffset);
    ADM_info("End  , seg %"PRIu32" Offset :%"PRIu64" ms\n",endSeg,endOffset);
    ListOfSegments tmp=segments;
    

    if(startSeg==endSeg)
    {
        // Split the seg int two..
        segments.insert(segments.begin()+startSeg+1,*getSegment(startSeg));
        endSeg=startSeg+1;

    }
    _SEGMENT *first=getSegment(startSeg);
      // Span over several seg...
    // 1- shorten the start segment..

    first->_durationUs=startOffset;

    // 3- Shorten last segment
    _SEGMENT *last=getSegment(endSeg);
    last->_refStartTimeUs+=endOffset;
    last->_durationUs-=endOffset;
    // 2- Kill the segment in between
    for(int i=startSeg+1;i<endSeg;i++)
    {
        segments.erase(segments.begin()+startSeg+1);
    }
    updateStartTime();
    removeEmptySegments();
    if(isEmpty())
    {
        GUI_Error_HIG(QT_TRANSLATE_NOOP("adm","Error"),QT_TRANSLATE_NOOP("adm","You cannot remove *all* the video\n"));
        segments=tmp;
        updateStartTime();
        return false;

    }
    undoSegments.push_back(tmp);
    dump();
    return true;
}
bool        ADM_Composer::addAudioTrack(int poolIndex)
{
    ADM_info("** Adding active track from pool **\n");
    activeAudioTracks.addTrack(poolIndex,audioTrackPool.at(poolIndex));
    ADM_info("Adding track %d\n",poolIndex);
    activeAudioTracks.dump();
    return true;
}
/**
 * \fn uncompress
 * \brief 
 * @param in
 * @param out
 * @return 
 */
bool decoderFFLIBVA::uncompress (ADMCompressedImage * in, ADMImage * out)
{
      
    aprintf("==> uncompress %s\n",_context->codec->long_name);
    if(out->refType==ADM_HW_LIBVA)
    {
            ADM_vaSurface *img=(ADM_vaSurface *)out->refDescriptor.refHwImage;
            markSurfaceUnused(img);
            out->refType=ADM_HW_NONE;
    }

    if (!in->dataLength )	// Null frame, silently skipped
    {
        out->_noPicture = 1;
        out->Pts=ADM_COMPRESSED_NO_PTS;
        out->refType=ADM_HW_NONE;
        ADM_info("[LibVa] Nothing to decode -> no Picture\n");
        return false;
    }

   // Put a safe value....
    out->Pts=in->demuxerPts;
    _context->reordered_opaque=in->demuxerPts;
    int got_picture;
    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data=in->data;
    pkt.size=in->dataLength;
    if(in->flags&AVI_KEY_FRAME)
        pkt.flags=AV_PKT_FLAG_KEY;
    else
        pkt.flags=0;
    
    AVFrame *frame=_parent->getFramePointer();
    ADM_assert(frame);
    int ret = avcodec_decode_video2 (_context, frame, &got_picture, &pkt);
    
    if(ret<0)
    {
        char er[2048]={0};
        av_make_error_string(er, sizeof(er)-1, ret);
        ADM_warning("Error %d in lavcodec (%s)\n",ret,er);
        out->refType=ADM_HW_NONE;
        return false;
    }
    if(frame->pict_type==AV_PICTURE_TYPE_NONE)
    {
        out->_noPicture=true;
        out->refType=ADM_HW_NONE;
        out->Pts= (uint64_t)(frame->reordered_opaque);
        ADM_info("[LIBVA] No picture \n");
        return false;
    }
    return readBackBuffer(frame,in,out);  
}
Example #21
0
/**
    \fn setDtsFromPts
    \brief For mpeg4 SP/ASP, recompute PTS DTS using the simple I/P/B frame reordering
    Works also for mpeg1/2
    It absolutely NEEDS to have the proper frame type set (PTS/DTS/...)
*/
bool setPtsFromDts(vidHeader *hdr,uint64_t timeIncrementUs,uint64_t *delay)
{
    int last=0;
    int nbFrames;
    int nbBframe=0;
    int maxBframe=0;
    uint32_t flags;
    uint64_t pts,dts;

    ADM_info("computing pts...\n");
    aviInfo info;
    hdr->getVideoInfo(&info);
    nbFrames=info.nb_frames;
    for(int i=1;i<nbFrames;i++)
    {
        hdr->getFlags(i,&flags);
        if(true!=hdr->getPtsDts(i,&pts,&dts))
        {
                    ADM_warning("Cannot get PTS/DTS\n");
                    return false;
        }
        if(flags & AVI_B_FRAME) nbBframe++;
        else        
            {
                if(nbBframe>maxBframe) maxBframe=nbBframe;
                nbBframe=0;
            }
    }
    ADM_info("max bframe = %d\n",maxBframe);
    nbBframe=0;
    // We have now maxBframe = max number of Bframes in sequence
    for(int i=1;i<nbFrames;i++)
    {
        hdr->getFlags(i,&flags);
        hdr->getPtsDts(i,&pts,&dts);
        if(flags & AVI_B_FRAME)
        {
            pts=dts;
            hdr->setPtsDts(i,pts,dts);
            nbBframe++;
        }
        else
        {
            uint64_t oldPts,oldDts;
            uint64_t fwdPts,fwdDts;
              hdr->getPtsDts(last,&oldPts,&oldDts);
              hdr->getPtsDts(i,&fwdPts,&fwdDts);
              oldPts=fwdDts;
              hdr->setPtsDts(last,oldPts,oldDts);
              last=i;
        }
    }
    return 1;
}
/**
    \fn encode
    \brief Get an encoded dca packet
    @param dest [in] Where to write datas
    @param len  [out] Length of encoded datas in bytes
    @param samples [out] Number of samples
    @return true on success, false on error

*/
bool AUDMEncoder_DcaEnc::encode(uint8_t *dest, uint32_t *len, uint32_t *samples)
{

  int32_t nbout;
  int neededSamples=inputSize*wavheader.channels;
  *samples = inputSize;	//FIXME
  *len = 0;
  if(AudioEncoderStopped==_state)
        return false;

    refillBuffer (neededSamples);
    if(AudioEncoderNoInput==_state)
    {
        int left=tmptail-tmphead;
        if (left < neededSamples)
        {
            if(left)
            {
                nbout=send(left,dest);
                tmphead=tmptail;
                ADM_info("[dcaenc]Sending last packet\n");
                goto cont;
            }
              // Flush
              _state=AudioEncoderStopped;
              // flush pad with 0n todo
              if(nbout<0)
              {
                    ADM_warning("Error while flushing dcaenc\n");
                    return false;
              }

              *len=nbout;
              *samples=inputSize;
              ADM_info("[dcaenc] Flushing, last block is %d bytes\n",nbout);
              return true;
    }
  }
  nbout=send(neededSamples,dest);
  tmphead += neededSamples;
cont:
  if (nbout < 0)
    {
      printf ("[dcaenc] Error !!! : %"PRIi32"\n", nbout);
      return false;
    }
  *len = nbout;
  if (!*len)
    *samples =0;
  else
    *samples=inputSize;
  return true;
}
/**
    \fn encode
    \brief Get an encoded mp3 packet
    @param dest [in] Where to write datas
    @param len  [out] Length of encoded datas in bytes
    @param samples [out] Number of samples
    @return true on success, false on error

*/
bool AUDMEncoder_Lame::encode(uint8_t *dest, uint32_t *len, uint32_t *samples)
{

  int32_t nbout;

  *samples = BLOCK_SIZE;	//FIXME
  *len = 0;
  if(AudioEncoderStopped==_state)
        return false;

    refillBuffer (_chunk);
    if(AudioEncoderNoInput==_state)
    {
        int left=tmptail-tmphead;
        if (left < _chunk)
        {
            if(left)
            {
                nbout=send(left,dest);
                tmphead=tmptail;
                ADM_info("[lame]Sending last packet\n");
                goto cont;
            }
              // Flush
              _state=AudioEncoderStopped;
              nbout=lame_encode_flush(MYFLAGS,dest,16*1024);
              if(nbout<0) 
              {
                    ADM_warning("Error while flushing lame\n");
                    return false;   
              }
                    
              *len=nbout;
              *samples=BLOCK_SIZE;  
              ADM_info("[Lame] Flushing, last block is %d bytes\n",nbout);
              return true;
    }
  }
  nbout=send(_chunk,dest);
  tmphead += _chunk;
cont:
  if (nbout < 0)
    {
      printf ("[Lame] Error !!! : %"PRIi32"\n", nbout);
      return false;
    }
  *len = nbout;
  if (!*len)
    *samples = 0;
  else
    *samples=BLOCK_SIZE;
  return true;
}
Example #24
0
/**
    \fn setup
*/
bool ADM_ffVAEncHEVC::setup(void)
{
    if(false== ADM_coreVideoEncoderFFmpeg::setupByName("hevc_vaapi"))
    {
        ADM_info("[ffMpeg] Setup failed\n");
        return false;
    }

    ADM_info("[ffMpeg] Setup ok\n");

    return true;
}
/**
    \fn dxvaRender
*/
dxvaRender::~dxvaRender()
{
    if(videoWidget)
    {
        videoWidget->useExternalRedraw(false); // reactivate Qt double buffering
        videoWidget->setDrawer(NULL);
        videoWidget=NULL;
    }
    ADM_info("dxva2/D3D clean up\n");
    cleanup();
    ADM_info("dxva2/D3D cleaned up\n");
}
bool spawnProcess(const char *processName, int argc, const string argv[])
{
    ADM_info("Starting <%s>\n",processName);
    string command=string(processName);
    for(int i=0;i<argc;i++)
    {
        ADM_info("%d : %s\n",i,argv[i].c_str());
        command+=string(" ")+argv[i];
    }
    ADM_info("=>%s\n",command.c_str());
    ADM_info("==================== Start of spawner process job ================\n");

#ifdef _WIN32
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );
    // utf8 -> utf16
    const char *c=command.c_str();
    int size=utf8StringToWideChar(c,strlen(c),NULL);
    wchar_t* w = new wchar_t[size+1];

    utf8StringToWideChar(c,strlen(c),w);
    // Start the child process. 
    if( !CreateProcessW( 
        NULL,   // No module name (use command line)
        w,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    )
    {
        delete [] w;
        ADM_error("Cannot spawn process! (%s)\n",c);
        return false;
    }

    delete [] w;
    
#else
    system(command.c_str());
#endif
    ADM_info("==================== End of spawner process job ================\n");
    return true;
}
Example #27
0
/**
 * 
 * @param avctx
 * @return 
 */
static bool  probeCuda()
{
   
    ADM_info( "Probing cuda\n");
    if(!loadCuda())
    {
        ADM_warning("Cannot load cuda\n");
        return false;
    }
    ADM_warning("Cuda loaded, probing..\n");
    if(!cudaCall(init(0)))
        return false;

    int deviceCount=0;
    if(!cudaCall(getDeviceCount(&deviceCount)))
        return false;

    if (!deviceCount) 
    {
        ADM_warning( "No Cuda device available\n");
        return false;
    }

    ADM_info( "found %d CUDA devices \n", deviceCount);

    for (int i = 0; i < deviceCount; ++i) 
    {
        CUdevice dev;
        char chipName[128];
        int major,minor,ver;
        
        cudaAbortOnFail(getDevice(&dev,i));
        cudaAbortOnFail(getDeviceName(chipName,sizeof(chipName),dev));
        cudaAbortOnFail(getDeviceCapabilities(&major,&minor,dev));
        ver = (major << 4) | minor;
        ADM_info("Found  chip, GPU %s, SM %d.d",chipName,major,minor);
        if(ver>=0x30)
        {
            ADM_info("   this chip has nvenc");
            if(!nvEncAvailable)
            {
                nvEncAvailable=true;
                selectedDevice=dev;
            }
        }
    }

    return nvEncAvailable;
abortCudaProbe:
    return false;
            
}
/**
    \fn stop
*/
bool sdlRenderImpl::stop( void)
{
        ADM_info("[SDL] Stopping\n");
        cleanup();
        if(sdl_running)
        {            
            ADM_info("[SDL] Video subsystem closed\n");
            SDL_QuitSubSystem(SDL_INIT_VIDEO);
            sdl_running=0;
        }
        
        return true;
}
static int loadTranslation(QTranslator *qTranslator, QString translation)
{
	ADM_info("[Locale] Loading language file %s ", translation.toUtf8().constData());

	if (qTranslator->load(translation))
	{
		QApplication::installTranslator(qTranslator);
		ADM_info("succeeded\n");
        return 1;
	}
    ADM_warning("FAILED\n");
    return 0;
}
/**
    \fn listOfPsAudioTracks
    \brief returns a list of audio track found, null if none found

*/
listOfPsAudioTracks *psProbeAudio(const char *fileName)
{
    uint32_t size;
    uint64_t dts,pts,startAt;
    uint8_t buffer[PACKET_PROBE_SIZE];
    uint64_t fileSize;

    listOfPsAudioTracks *tracks=new listOfPsAudioTracks;
    psPacketLinearTracker *packet=new psPacketLinearTracker(0xE0);

    printf("[MpegPS] Probing audio for %s\n",fileName);

    if(!packet->open(fileName,FP_APPEND)) goto end;
    fileSize=packet->getSize();

    packet->setPos(fileSize/2); // Jump in the middle of the stream

    while(packet->getPacketOfType(0xE0,PACKET_PROBE_SIZE,&size,&dts,&pts,buffer,&startAt))
    {
        packetStats *stat=packet->getStat(0xE0);
        if(stat->count > PROBE_PACKET_VIDEO_COUNT)
                break;
    }
    // Now synthetize
    for(int i=0x0;i<0xFF;i++)
    {
        packetStats *stat=packet->getStat(i);
        if(stat->count)
        {
            ADM_info("[PsProbeAudo] Pid:%x count:%" PRIx32" size:%" PRIi32"\n",i,stat->count,stat->size);
            if(stat->count>=PROBE_MIN_PACKET && stat->size>PROBE_MIN_SIZE)
            {
                packet->setPos(fileSize/2);
                addAudioTrack(i,tracks,packet);
            }else       
                ADM_info("[PsProbeAudo] Not enough samples\n");
        }
    }

end:
    ADM_info("[PsDemux] Audio probe done, found %d tracks\n",(int)tracks->size());
    delete packet;

    if(tracks->size()==0)
    {
        delete tracks;
        return NULL;
    }
    return tracks;
}