Esempio n. 1
0
File: api.cpp Progetto: VIasai/x265
x265_encoder *x265_encoder_open(x265_param *p)
{
    if (!p)
        return NULL;

    Encoder* encoder = NULL;
    x265_param* param = PARAM_NS::x265_param_alloc();
    x265_param* latestParam = PARAM_NS::x265_param_alloc();
    if (!param || !latestParam)
        goto fail;

    memcpy(param, p, sizeof(x265_param));
    x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n", PFX(version_str));
    x265_log(param, X265_LOG_INFO, "build info %s\n", PFX(build_info_str));

    x265_setup_primitives(param, param->cpuid);

    if (x265_check_params(param))
        goto fail;

    if (x265_set_globals(param))
        goto fail;

    encoder = new Encoder;
    if (!param->rc.bEnableSlowFirstPass)
        PARAM_NS::x265_param_apply_fastfirstpass(param);

    // may change params for auto-detect, etc
    encoder->configure(param);
    // may change rate control and CPB params
    if (!enforceLevel(*param, encoder->m_vps))
        goto fail;

    // will detect and set profile/tier/level in VPS
    determineLevel(*param, encoder->m_vps);

    if (!param->bAllowNonConformance && encoder->m_vps.ptl.profileIdc == Profile::NONE)
    {
        x265_log(param, X265_LOG_INFO, "non-conformant bitstreams not allowed (--allow-non-conformance)\n");
        goto fail;
    }

    encoder->create();
    encoder->m_latestParam = latestParam;
    memcpy(latestParam, param, sizeof(x265_param));
    if (encoder->m_aborted)
        goto fail;

    x265_print_params(param);
    return encoder;

fail:
    delete encoder;
    PARAM_NS::x265_param_free(param);
    PARAM_NS::x265_param_free(latestParam);
    return NULL;
}
Esempio n. 2
0
x265_encoder *x265_encoder_open(x265_param *p)
{
    if (!p)
        return NULL;

    x265_param *param = X265_MALLOC(x265_param, 1);
    if (!param)
        return NULL;

    memcpy(param, p, sizeof(x265_param));
    x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n", x265_version_str);
    x265_log(param, X265_LOG_INFO, "build info %s\n", x265_build_info_str);

    x265_setup_primitives(param, param->cpuid);

    if (x265_check_params(param))
        return NULL;

    if (x265_set_globals(param))
        return NULL;

    Encoder *encoder = new Encoder;
    if (!param->rc.bEnableSlowFirstPass)
        x265_param_apply_fastfirstpass(param);

    // may change params for auto-detect, etc
    encoder->configure(param);
    
    // may change rate control and CPB params
    if (!enforceLevel(*param, encoder->m_vps))
    {
        delete encoder;
        return NULL;
    }

    // will detect and set profile/tier/level in VPS
    determineLevel(*param, encoder->m_vps);

    if (!param->bAllowNonConformance && encoder->m_vps.ptl.profileIdc == Profile::NONE)
    {
        x265_log(param, X265_LOG_INFO, "non-conformant bitstreams not allowed (--allow-non-conformance)\n");
        delete encoder;
        return NULL;
    }

    encoder->create();
    if (encoder->m_aborted)
    {
        delete encoder;
        return NULL;
    }

    x265_print_params(param);

    return encoder;
}
Esempio n. 3
0
x265_encoder *x265_encoder_open(x265_param *p)
{
    if (!p)
        return NULL;

#if _MSC_VER
#pragma warning(disable: 4127) // conditional expression is constant, yes I know
#endif

#if HIGH_BIT_DEPTH
    if (X265_DEPTH != 10 && X265_DEPTH != 12)
#else
    if (X265_DEPTH != 8)
#endif
    {
        x265_log(p, X265_LOG_ERROR, "Build error, internal bit depth mismatch\n");
        return NULL;
    }

    Encoder* encoder = NULL;
    x265_param* param = PARAM_NS::x265_param_alloc();
    x265_param* latestParam = PARAM_NS::x265_param_alloc();
    if (!param || !latestParam)
        goto fail;

    memcpy(param, p, sizeof(x265_param));
    x265_log(param, X265_LOG_INFO, "HEVC encoder version %s\n", PFX(version_str));
    x265_log(param, X265_LOG_INFO, "build info %s\n", PFX(build_info_str));

    x265_setup_primitives(param);

    if (x265_check_params(param))
        goto fail;

    if (x265_set_globals(param))
        goto fail;

    encoder = new Encoder;
    if (!param->rc.bEnableSlowFirstPass)
        PARAM_NS::x265_param_apply_fastfirstpass(param);

    // may change params for auto-detect, etc
    encoder->configure(param);
    // may change rate control and CPB params
    if (!enforceLevel(*param, encoder->m_vps))
        goto fail;

    // will detect and set profile/tier/level in VPS
    determineLevel(*param, encoder->m_vps);

    if (!param->bAllowNonConformance && encoder->m_vps.ptl.profileIdc == Profile::NONE)
    {
        x265_log(param, X265_LOG_INFO, "non-conformant bitstreams not allowed (--allow-non-conformance)\n");
        goto fail;
    }

    encoder->create();
    encoder->m_latestParam = latestParam;
    memcpy(latestParam, param, sizeof(x265_param));
    if (encoder->m_aborted)
        goto fail;

    x265_print_params(param);
    return encoder;

fail:
    delete encoder;
    PARAM_NS::x265_param_free(param);
    PARAM_NS::x265_param_free(latestParam);
    return NULL;
}
uint8_t oplug_mpegff(const char *name, ADM_OUT_FORMAT type)
{
AVDMGenericVideoStream *_incoming;
//EncoderFFMPEGMpeg1  *encoder;
Encoder  *encoder;

ADMMpegMuxer	*muxer=NULL;
FILE 		*file=NULL;
uint8_t		audioBuffer[48000];
uint32_t	audioLen=0;
uint32_t _w,_h,_fps1000,_page,total;	
AVDMGenericAudioStream	*audio;
uint32_t len,flags;
uint32_t size;
ADM_MUXER_TYPE mux;
uint32_t  audio_encoding=0;
uint32_t  real_framenum=0;
uint8_t   ret=0;
uint32_t  sample_target=0;
uint32_t  total_sample=0;
ADMBitstream bitstream(0);
uint32_t audioSum=0;

        twoPass=new char[strlen(name)+6];
        twoFake=new char[strlen(name)+6];
  
        strcpy(twoPass,name);
        strcat(twoPass,".stat");
        /* orig: strcat(twoFake,".fake"); */

        strcpy(twoFake,name);
        strcat(twoFake,".fake");
 
        _incoming = getLastVideoFilter (frameStart,frameEnd-frameStart);
        _w=_incoming->getInfo()->width;
        _h=_incoming->getInfo()->height;
        _fps1000=_incoming->getInfo()->fps1000;
        _page=_w*_h;
        _page+=_page>>1;

        total=_incoming->getInfo()->nb_frames;
        if(!total) return 0;	
        
        switch(type)
        {
            default:
                    ADM_assert(0);
            case ADM_ES:
                        // Else open file (if possible)                       
                        mux=MUXER_NONE;
                        break;
            case ADM_TS:
                    if(!currentaudiostream)
                    {
                      GUI_Error_HIG(_("There is no audio track"), NULL);
                        return 0;
                    }
                    audio=mpt_getAudioStream();
                    mux=MUXER_TS;
                    break;
            case ADM_PS:
            
            {
                if(!currentaudiostream)
                {
                  GUI_Error_HIG(_("There is no audio track"), NULL);
                        return 0;
                }
                audio=mpt_getAudioStream();
                // Have to check the type
                // If it is mpeg2 we use DVD-PS
                // If it is mpeg1 we use VCD-PS
                // Later check if it is SVCD
                if(!audio)
                {
                  GUI_Error_HIG(_("Audio track is not suitable"), NULL);
                        return 0;
                }
                // Check
                WAVHeader *hdr=audio->getInfo();	
                audio_encoding=hdr->encoding;
                if(current_codec==CodecXVCD ||current_codec==CodecVCD)
                {
                        if(hdr->frequency!=44100 ||  hdr->encoding != WAV_MP2)
                        {
                            GUI_Error_HIG(("Incompatible audio"),_( "For VCD, audio must be 44.1 kHz MP2."));
                            deleteAudioFilter(audio);
                            return 0;
                        }
                        mux=MUXER_VCD;
                        printf("X*CD: Using VCD PS\n");
                }else
                {    
                        aviInfo info;
                        video_body->getVideoInfo(&info);
                        if(hdr->frequency==44100 && _w==480&&hdr->encoding == WAV_MP2 ) // SVCD ?
                        {
                            mux=MUXER_SVCD;
                            printf("X*VCD: Using SVCD PS\n");
                        }
                        else
                        {
                            // mpeg2, we do only DVD right now
                            if(hdr->frequency!=48000 || 
                                (hdr->encoding != WAV_MP2 && hdr->encoding!=WAV_AC3 && hdr->encoding!=WAV_LPCM))
                            {
                                deleteAudioFilter(audio);
                                GUI_Error_HIG(_("Incompatible audio"), _("For DVD, audio must be 48 kHz MP2, AC3 or LPCM."));
                                return 0 ;
                            }
                            mux=MUXER_DVD;
                            printf("X*VCD: Using DVD PS\n");
                        }
                }
            }
         }        
        // Create muxer
       
       
        switch(current_codec)
        {
                
                case CodecXVCD:
                        encoder=new EncoderFFMPEGMpeg1(FF_MPEG1,&ffmpeg1Codec);
                        printf("\n Using ffmpeg mpeg1 encoder\n");
                        break;
                case CodecXSVCD:
                        encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2SVCDCodec);
                        printf("\n Using ffmpeg mpeg2 encoder\n");
                        break;
                case CodecXDVD:
                        encoder=new EncoderFFMPEGMpeg1(FF_MPEG2,&ffmpeg2DVDCodec);
                        printf("\n Using ffmpeg mpeg2 encoder (DVD)\n");
                        break;
                case CodecDVD:
                  encoder=new EncoderMpeg2enc(MPEG2ENC_DVD,&DVDCodec);
                  printf("\n Using mpeg2enc encoder (DVD)\n");
                  break;
                case CodecRequant:
                  if(!isMpeg12Compatible(avifileinfo->fcc))
                  {
                    GUI_Error_HIG("Incompatible Input","The input file must be mpeg2 to be able to use requant!");
                    return 0; // Fixme, do some cleanup 
                  }
                  encoder=new EncoderRequant(&RequantCodec);
                  printf("\n Using mpeg2 requant\n");
                  break;
                break;
                case CodecSVCD:
                  encoder=new EncoderMpeg2enc(MPEG2ENC_SVCD,&SVCDCodec);
                  printf("\n Using mpeg2enc encoder (SVCD)\n");
                  break;
                case CodecVCD:
                  encoder=new EncoderMpeg2enc(MPEG2ENC_VCD,&VCDCodec);
                  printf("\n Using mpeg2enc encoder (VCD)\n");
                  break;
                default:
                ADM_assert(0);
      }

      encoder->setLogFile(twoPass,total);
      if(!encoder->configure(_incoming))
      {
              delete encoder;
              return 0;
      }


      _buffer=new uint8_t[_page]; // Might overflow if _page only
      _outbuffer=new uint8_t[_page];

      ADM_assert(  _buffer);
      ADM_assert(  _outbuffer);
    
      DIA_encoding  *encoding;
      encoding =new DIA_encoding(_fps1000);
      switch(current_codec)
      {
          case CodecVCD:
            encoding->setCodec("libmpeg2enc VCD");
            break;
          case CodecSVCD:
            encoding->setCodec("libmpeg2enc SVCD");
            break;
          case CodecDVD:
            encoding->setCodec("libmpeg2enc DVD");
            break;
          case CodecXVCD:
            encoding->setCodec("FFmpeg Mpeg1 VBR");
            break;
          case CodecXSVCD:
            encoding->setCodec("FFmpeg Mpeg2 SVCD VBR");
            break;
          case CodecXDVD:
            encoding->setCodec("FFmpeg Mpeg2 DVD VBR");
            break;
          case CodecRequant:
            encoding->setCodec("Mpeg Requantizer");
            break;
          
          default:
            ADM_assert(0);
	}
        switch(mux)
          {
            case MUXER_NONE:encoding->setContainer("Mpeg ES");break;
            case MUXER_TS:  encoding->setContainer("Mpeg TS");break;
            case MUXER_VCD: encoding->setContainer("Mpeg VCD");break;
            case MUXER_SVCD:encoding->setContainer("Mpeg SVCD");break;
            case MUXER_DVD: encoding->setContainer("Mpeg DVD");break;
            default:
                ADM_assert(0);
          }



        // pass 1
        if(encoder->isDualPass())
        {
                        FILE *fd;
                        uint8_t reuse=0;
                        fd=fopen(twoPass,"rt");
                        if(fd)
                        {
                          if(GUI_Question(_("Reuse log file ?")))
                                {
                                        reuse=1;
                                }
                                fclose(fd);
                        }
                        if(!reuse)
                        {
                                encoding->setPhasis ("Pass 1/2");
                                encoder->startPass1();
                                bitstream.data=_buffer;
                                bitstream.bufferSize=_page;
                                for(uint32_t i=0;i<total;i++)
                                {
                                        bitstream.cleanup(i);
                                        if(!encoder->encode( i, &bitstream))//&len,(uint8_t *) _buffer,&flags))
                                        {
                                          GUI_Error_HIG(_("Error in pass 1"), NULL);
                                        }
                                        encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total);
                                        if(!encoding->isAlive())
                                        {

                                              goto finishvcdff;
                                        }
                                }
                        }
                        encoder->startPass2();
                        encoding->reset();
                }
                
              switch(type)
              {
                case ADM_PS:
                  muxer=new mplexMuxer;
                  break;
                case ADM_TS:
                  muxer=new tsMuxer;
                  break;
                case ADM_ES:
                  break;
                default:
                  ADM_assert(0);
      
      
              }
              if(muxer)
              {
                if(!muxer->open(name,0,mux,avifileinfo,audio->getInfo()))
                {
                  delete muxer;
                  muxer=NULL;
                  deleteAudioFilter(audio);
                  printf("Muxer init failed\n");
                  return 0 ;
                }
                double sample_time;

                sample_time=total;
                sample_time*=1000;
                sample_time/=_fps1000; // target_time in second
                sample_time*=audio->getInfo()->frequency;
                sample_target=(uint32_t)floor(sample_time);
              }
              else
              {
                file=fopen(name,"wb");
                if(!file)
                {
                  GUI_Error_HIG(_("File error"), _("Cannot open \"%s\" for writing."), name);
                  return 0 ;
                }
              }
          if(encoder->isDualPass())
                  encoding->setPhasis ("Pass 2/2");
          else
                  encoding->setPhasis ("Encoding");

         // Set info for audio if any
         if(muxer)
         {
            if(!audioProcessMode())
                  encoding->setAudioCodec("Copy");
            else
                  encoding->setAudioCodec(getStrFromAudioCodec(audio->getInfo()->encoding));
         }
         //**********************************************************
         //  In that case we do multithreadedwriting (yes!)
         //**********************************************************

         if(mux==MUXER_DVD || mux==MUXER_SVCD || mux==MUXER_VCD)
         {
           pthread_t audioThread,videoThread,muxerThread;
           muxerMT context;
           //
           bitstream.data=_outbuffer;
           bitstream.bufferSize=_page;
           // 
           memset(&context,0,sizeof(context));
           context.videoEncoder=encoder;
           context.audioEncoder=audio;
           context.muxer=(mplexMuxer *)muxer;
           context.nbVideoFrame=total;
           context.audioTargetSample=sample_target;
           context.audioBuffer=audioBuffer;
           context.bitstream=&bitstream;
           context.opaque=(void *)encoding;

           // start audio thread
           ADM_assert(!pthread_create(&audioThread,NULL,(THRINP)defaultAudioSlave,&context)); 
           ADM_assert(!pthread_create(&videoThread,NULL,(THRINP)defaultVideoSlave,&context)); 
           while(1)
           {
             accessMutex.lock();
             if(!encoding->isAlive())
             {
               context.audioAbort=1;
               context.videoAbort=1;
               printf("[mpegFF]Waiting for slaves\n");
               accessMutex.unlock();
               while(1)
               {
                 accessMutex.lock();
                 if(context.audioDone && context.videoDone)
                 {
                   printf("[mpegFF]Both audio & video done\n");
                   if(context.audioDone==1 && context.videoDone==1) ret=1;
                   else ret=0;
                   accessMutex.unlock();
                   goto finishvcdff;
                 }
                 accessMutex.unlock();
                 ADM_usleep(50000);
 
               }
               
             }
             if(context.audioDone==2 || context.videoDone==2 ) //ERROR
             {
               context.audioAbort=1;
               context.videoAbort=1;
             }
             if(context.audioDone && context.videoDone)
             {
               printf("[mpegFF]Both audio & video done\n");
               if(context.audioDone==1 && context.videoDone==1) ret=1;
               else ret=0;
               accessMutex.unlock();
               goto finishvcdff;
             }
             accessMutex.unlock();
             ADM_usleep(1000*1000);
             
           }
           
         }
         //**********************************************************
         //  NOT MULTITHREADED
         //**********************************************************

      bitstream.data=_outbuffer;
      for(uint32_t i=0;i<total;i++)
      {
       	// get frame
                bitstream.cleanup(i);
                if(!encoder->encode( i,&bitstream))// &len,(uint8_t *) _outbuffer,&flags))
                {
                  GUI_Error_HIG(_("Error in pass 2"), NULL);
                        goto finishvcdff;
                }
                if(!bitstream.len) continue;
                
                if(file)
                {
                    fwrite(_outbuffer,bitstream.len,1,file);
                }
                else
                {
                        uint32_t samples; 
                        
                        //printf("%lu %lu\n",i,dts);
                        
                        muxer->writeVideoPacket(&bitstream);
                        real_framenum++;
                        // _muxer->writeVideoPacket(len,_buffer_out,
                        //i-MPEG_PREFILL,_codec->getCodedPictureNumber());
                        if(total_sample<sample_target)
                        {
                            while(muxer->needAudio() && total_sample<sample_target) 
                            {				
                                if(!audio->getPacket(audioBuffer, &audioLen, &samples))	
                                { 
                                        break; 
                                }
                                if(audioLen) 
                                {
                                        muxer->writeAudioPacket(audioLen,audioBuffer); 
                                        total_sample+=samples;
                                        audioSum+=audioLen;
                                }
                            }
                        }
                
                }
                encoding->setFrame(i,bitstream.len,bitstream.out_quantizer,total);
                encoding->setAudioSize(audioSum);
                if(!encoding->isAlive ())
                        {
                                  ret=0;        
                                  goto finishvcdff;
                        }
        }
        ret=1;
finishvcdff:
        printf("[MPEGFF] Finishing..\n");
        delete encoding;
        end();
        if(file)
        {
                fclose(file);
                file=NULL;
        }
        else
        {  
            if(muxer)
            {
                muxer->close();
                delete muxer;
                muxer=NULL;
            }
        }
        delete encoder;
        return ret;
}