2016-06-29 8 views
5

का उपयोग करते समय लटकता है जब मैं mpeg4 या h264 एन्कोडर्स का उपयोग करता हूं, तो मैं ffmpeg 3.1.0 के लिए API का उपयोग करके वैध AVI फ़ाइल बनाने के लिए छवियों को सफलतापूर्वक एन्कोड करने में सक्षम हूं। हालांकि, जब मैं क्विक सिंक एन्कोडर (h264_qsv) का उपयोग करता हूं, तो avcodec_encode_video2 कुछ समय लटकाएगा। मैंने पाया कि 1920x1080 की छवियों का उपयोग करते समय, यह दुर्लभ था कि avcodec_encode_video2 लटका होगा। 256x256 छवियों का उपयोग करते समय, यह बहुत संभावना थी कि समारोह लटका होगा।ffmpeg avcodec_encode_video2 त्वरित सिंक h264_qsv एन्कोडर

मैंने नीचे दिया गया टेस्ट कोड बनाया है जो avcodec_encode_video2 का लटका प्रदर्शित करता है। कोड 400000 की थोड़ी दर के साथ एक 1000 फ्रेम, 256x256 एवीआई बनाएगा। फ्रेम को आवंटित किया जाता है, इसलिए आउटपुट वीडियो केवल हरे रंग के फ्रेम होना चाहिए।

समस्या 32-बिट या 64-बिट परीक्षण अनुप्रयोग का उपयोग करते हुए Windows 7 और Windows 10 का उपयोग करके देखी गई थी।

अगर किसी को यह पता है कि मैं avcodec_encode_video2 hang से कैसे बच सकता हूं तो मैं बहुत आभारी रहूंगा! किसी भी सहायता के लिए अग्रिम धन्यवाद।

extern "C" 
{ 
#ifndef __STDC_CONSTANT_MACROS 
#define __STDC_CONSTANT_MACROS 
#endif 
#include "avcodec.h" 
#include "avformat.h" 
#include "swscale.h" 
#include "avutil.h" 
#include "imgutils.h" 
#include "opt.h" 
#include <rational.h> 
} 

#include <iostream> 


// Globals 
AVCodec* m_pCodec = NULL; 
AVStream *m_pStream = NULL; 
AVOutputFormat* m_pFormat = NULL; 
AVFormatContext* m_pFormatContext = NULL; 
AVCodecContext* m_pCodecContext = NULL; 
AVFrame* m_pFrame = NULL; 
int m_frameIndex; 

// Output format 
AVPixelFormat m_pixType = AV_PIX_FMT_NV12; 
// Use for mpeg4 
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P; 

// Output frame rate 
int m_frameRate = 30; 
// Output image dimensions 
int m_imageWidth = 256; 
int m_imageHeight = 256; 
// Number of frames to export 
int m_frameCount = 1000; 
// Output file name 
const char* m_fileName = "c:/test/test.avi"; 
// Output file type 
const char* m_fileType = "AVI"; 
// Codec name used to encode 
const char* m_encoderName = "h264_qsv"; 
// use for mpeg4 
//const char* m_encoderName = "mpeg4"; 
// Target bit rate 
int m_targetBitRate = 400000; 

void addVideoStream() 
{ 
    m_pStream = avformat_new_stream(m_pFormatContext, m_pCodec); 
    m_pStream->id = m_pFormatContext->nb_streams - 1; 
    m_pStream->time_base = m_pCodecContext->time_base; 
    m_pStream->codec->pix_fmt = m_pixType; 
    m_pStream->codec->flags = m_pCodecContext->flags; 
    m_pStream->codec->width = m_pCodecContext->width; 
    m_pStream->codec->height = m_pCodecContext->height; 
    m_pStream->codec->time_base = m_pCodecContext->time_base; 
    m_pStream->codec->bit_rate = m_pCodecContext->bit_rate; 
} 

AVFrame* allocatePicture(enum AVPixelFormat pix_fmt, int width, int height) 
{ 
    AVFrame *frame; 

    frame = av_frame_alloc(); 

    if (!frame) 
    { 
     return NULL; 
    } 

    frame->format = pix_fmt; 
    frame->width = width; 
    frame->height = height; 

    int checkImage = av_image_alloc(frame->data, frame->linesize, width, height, pix_fmt, 32); 

    if (checkImage < 0) 
    { 
     return NULL; 
    } 

    return frame; 
} 

bool initialize() 
{ 
    AVRational frameRate; 
    frameRate.den = m_frameRate; 
    frameRate.num = 1; 

    av_register_all(); 

    m_pCodec = avcodec_find_encoder_by_name(m_encoderName); 

    if(!m_pCodec) 
    { 
     return false; 
    } 

    m_pCodecContext = avcodec_alloc_context3(m_pCodec); 
    m_pCodecContext->width = m_imageWidth; 
    m_pCodecContext->height = m_imageHeight; 
    m_pCodecContext->time_base = frameRate; 
    m_pCodecContext->gop_size = 0; 
    m_pCodecContext->pix_fmt = m_pixType; 
    m_pCodecContext->codec_id = m_pCodec->id; 
    m_pCodecContext->bit_rate = m_targetBitRate; 

    av_opt_set(m_pCodecContext->priv_data, "+CBR", "", 0); 

    return true; 
} 

bool startExport() 
{ 
    m_frameIndex = 0; 
    char fakeFileName[512]; 
    int checkAllocContext = avformat_alloc_output_context2(&m_pFormatContext, NULL, m_fileType, fakeFileName); 

    if (checkAllocContext < 0) 
    { 
     return false; 
    } 

    if (!m_pFormatContext) 
    { 
     return false; 
    } 

    m_pFormat = m_pFormatContext->oformat; 

    if (m_pFormat->video_codec != AV_CODEC_ID_NONE) 
    { 
     addVideoStream(); 

     int checkOpen = avcodec_open2(m_pCodecContext, m_pCodec, NULL); 

     if (checkOpen < 0) 
     { 
      return false; 
     } 

     m_pFrame = allocatePicture(m_pCodecContext->pix_fmt, m_pCodecContext->width, m_pCodecContext->height);     
     if(!m_pFrame) 
     { 
      return false; 
     } 
     m_pFrame->pts = 0; 
    } 

    int checkOpen = avio_open(&m_pFormatContext->pb, m_fileName, AVIO_FLAG_WRITE); 
    if (checkOpen < 0) 
    { 
     return false; 
    } 

    av_dict_set(&(m_pFormatContext->metadata), "title", "QS Test", 0); 

    int checkHeader = avformat_write_header(m_pFormatContext, NULL); 
    if (checkHeader < 0) 
    { 
     return false; 
    } 

    return true; 
} 

int processFrame(AVPacket& avPacket) 
{ 
    avPacket.stream_index = 0; 
    avPacket.pts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base); 
    avPacket.dts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base); 
    m_pFrame->pts++; 

    int retVal = av_interleaved_write_frame(m_pFormatContext, &avPacket); 
    return retVal; 
} 

bool exportFrame() 
{ 
    int success = 1; 
    int result = 0; 

    AVPacket avPacket; 

    av_init_packet(&avPacket); 
    avPacket.data = NULL; 
    avPacket.size = 0; 

    fflush(stdout); 

    std::cout << "Before avcodec_encode_video2 for frame: " << m_frameIndex << std::endl; 
    success = avcodec_encode_video2(m_pCodecContext, &avPacket, m_pFrame, &result); 
    std::cout << "After avcodec_encode_video2 for frame: " << m_frameIndex << std::endl; 

    if(result) 
    { 
     success = processFrame(avPacket); 
    } 

    av_packet_unref(&avPacket); 

    m_frameIndex++; 
    return (success == 0); 
} 

void endExport() 
{ 
    int result = 0; 
    int success = 0; 

    if (m_pFrame) 
    { 
     while (success == 0) 
     { 
      AVPacket avPacket; 
      av_init_packet(&avPacket); 
      avPacket.data = NULL; 
      avPacket.size = 0; 

      fflush(stdout); 
      success = avcodec_encode_video2(m_pCodecContext, &avPacket, NULL, &result); 

      if(result) 
      { 
       success = processFrame(avPacket); 
      } 
      av_packet_unref(&avPacket); 

      if (!result) 
      { 
       break; 
      } 
     } 
    } 

    if (m_pFormatContext) 
    { 
     av_write_trailer(m_pFormatContext); 

     if(m_pFrame) 
     { 
      av_frame_free(&m_pFrame); 
     } 

     avio_closep(&m_pFormatContext->pb); 
     avformat_free_context(m_pFormatContext); 
     m_pFormatContext = NULL; 
    } 
} 

void cleanup() 
{ 
    if(m_pFrame || m_pCodecContext) 
    { 
     if(m_pFrame) 
     { 
      av_frame_free(&m_pFrame); 
     } 

     if(m_pCodecContext) 
     { 
      avcodec_close(m_pCodecContext); 
      av_free(m_pCodecContext); 
     } 
    } 
} 

int main() 
{ 
    bool success = true; 
    if (initialize()) 
    { 
     if (startExport()) 
     { 
      for (int loop = 0; loop < m_frameCount; loop++) 
      { 
       if (!exportFrame()) 
       { 
        std::cout << "Failed to export frame\n"; 
        success = false; 
        break; 
       } 
      } 
      endExport(); 
     } 
     else 
     { 
      std::cout << "Failed to start export\n"; 
      success = false; 
     } 

     cleanup(); 
    } 
    else 
    { 
     std::cout << "Failed to initialize export\n"; 
     success = false; 
    } 

    if (success) 
    { 
     std::cout << "Successfully exported file\n"; 
    } 
    return 1; 
} 
+0

यह भी avcodec_decode_video2() में लटकी हुई h264_qsv साथ - ffmpeg-2.8.8 – danishansari

उत्तर

-1

अब है कि मैं नवीनतम इंटेल ग्राफिक्स ड्राइवर को अद्यतन किया है समस्या नहीं रह गया है तब होता है (संस्करण 15.45.10.4542)

+1

आपको अपने प्रश्न को हटा देना चाहिए यदि यह ऐसी समस्या के कारण होता है जिसे अब पुन: उत्पन्न नहीं किया जा सकता है या एक साधारण टाइपोग्राफ़िकल त्रुटि – miken32

+0

मैंने नवीनतम इंटेल® ग्राफिक्स ड्राइवर (संस्करण 20.19.15.4624) में अपडेट किया है और अभी भी वही समस्या है। –