2010-07-26 90 views
4

我試圖將一系列圖像編碼爲一個視頻文件。我使用api-example.c代碼,它的作品,但它給了我奇怪的綠色在視頻。我知道,我需要我的RGB圖像轉換爲YUV,我發現了一些解決方案,但它不工作,顏色不是綠色的,但是很奇怪,因此多數民衆贊成代碼:使用ffmpeg將圖像編碼爲視頻

// Register all formats and codecs 
    av_register_all(); 

    AVCodec *codec; 
    AVCodecContext *c= NULL; 
    int i, out_size, size, outbuf_size; 
    FILE *f; 
    AVFrame *picture; 
    uint8_t *outbuf; 

    printf("Video encoding\n"); 

    /* find the mpeg video encoder */ 
    codec = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO); 
    if (!codec) { 
     fprintf(stderr, "codec not found\n"); 
     exit(1); 
    } 

    c= avcodec_alloc_context(); 
    picture= avcodec_alloc_frame(); 

    /* put sample parameters */ 
    c->bit_rate = 400000; 
    /* resolution must be a multiple of two */ 
    c->width = 352; 
    c->height = 288; 
    /* frames per second */ 
    c->time_base= (AVRational){1,25}; 
    c->gop_size = 10; /* emit one intra frame every ten frames */ 
    c->max_b_frames=1; 
    c->pix_fmt = PIX_FMT_YUV420P; 

    /* open it */ 
    if (avcodec_open(c, codec) < 0) { 
     fprintf(stderr, "could not open codec\n"); 
     exit(1); 
    } 

    f = fopen(filename, "wb"); 
    if (!f) { 
     fprintf(stderr, "could not open %s\n", filename); 
     exit(1); 
    } 

    /* alloc image and output buffer */ 
    outbuf_size = 100000; 
    outbuf = malloc(outbuf_size); 
    size = c->width * c->height; 

#pragma mark - 
    AVFrame* outpic = avcodec_alloc_frame(); 
    int nbytes = avpicture_get_size(PIX_FMT_YUV420P, c->width, c->height); 

    //create buffer for the output image 
    uint8_t* outbuffer = (uint8_t*)av_malloc(nbytes); 

#pragma mark - 
    for(i=1;i<77;i++) { 
     fflush(stdout); 

     int numBytes = avpicture_get_size(PIX_FMT_YUV420P, c->width, c->height); 
     uint8_t *buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); 

     UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"10%d", i]]; 
     CGImageRef newCgImage = [image CGImage]; 

     CGDataProviderRef dataProvider = CGImageGetDataProvider(newCgImage); 
     CFDataRef bitmapData = CGDataProviderCopyData(dataProvider); 
     buffer = (uint8_t *)CFDataGetBytePtr(bitmapData); 

     avpicture_fill((AVPicture*)picture, buffer, PIX_FMT_RGB8, c->width, c->height); 
     avpicture_fill((AVPicture*)outpic, outbuffer, PIX_FMT_YUV420P, c->width, c->height); 

     struct SwsContext* fooContext = sws_getContext(c->width, c->height, 
               PIX_FMT_RGB8, 
               c->width, c->height, 
               PIX_FMT_YUV420P, 
               SWS_FAST_BILINEAR, NULL, NULL, NULL); 

     //perform the conversion 
     sws_scale(fooContext, picture->data, picture->linesize, 0, c->height, outpic->data, outpic->linesize); 
     // Here is where I try to convert to YUV 

     /* encode the image */ 
     out_size = avcodec_encode_video(c, outbuf, outbuf_size, outpic); 
     printf("encoding frame %3d (size=%5d)\n", i, out_size); 
     fwrite(outbuf, 1, out_size, f); 

     free(buffer); 
     buffer = NULL;  

    } 

    /* get the delayed frames */ 
    for(; out_size; i++) { 
     fflush(stdout); 

     out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); 
     printf("write frame %3d (size=%5d)\n", i, out_size); 
     fwrite(outbuf, 1, outbuf_size, f);  
    } 

    /* add sequence end code to have a real mpeg file */ 
    outbuf[0] = 0x00; 
    outbuf[1] = 0x00; 
    outbuf[2] = 0x01; 
    outbuf[3] = 0xb7; 
    fwrite(outbuf, 1, 4, f); 
    fclose(f); 
    free(outbuf); 

    avcodec_close(c); 
    av_free(c); 
    av_free(picture); 
    printf("\n"); 

請給我意見如何解決這個問題。

+0

1個問題。上面的代碼需要什麼框架? – aryaxt 2010-08-28 20:07:27

+0

它需要FFmpeg庫http://www.ffmpeg.org/。 – Steve 2010-08-30 07:36:58

+0

我也面臨着同樣的問題...你能幫我解決你的問題.... – Ganesh 2011-06-04 13:04:54

回答

0

我認爲這個問題很可能是您使用PIX_FMT_RGB8作爲您的輸入像素格式。這並不意味着每通道8位像常用的24位RGB或32位ARGB。它意味着每個像素8位,這意味着所有三個顏色通道都位於一個字節中。我猜這不是你的圖像的格式,因爲它很不常見,所以你需要使用PIX_FMT_RGB24PIX_FMT_RGB32,這取決於你的輸入圖像是否有alpha通道。有關像素格式的信息,請參閱this documentation頁面。

+0

謝謝。我試過PIX_FMT_RGB24和PIX_FMT_RGB32等等。我使用PIX_FMT_RGB8,因爲我的圖像針對網絡進行了優化,其索引8位顏色png和其他photoshop東西使其更小。但是我用通常的格式嘗試了其他圖像,只是爲了檢查PIX_FMT的不同選項,它仍然給我錯誤的結果,所以我認爲在代碼中遇到了麻煩。 – Steve 2010-07-27 06:48:19

+0

你試過PIX_FMT_PAL8嗎?該格式適用於8位索引顏色。使用PIX_FMT_PAL8時,必須隨框架一起發送調色板。在定義所有像素格式之前,我鏈接的那個文檔頁面正好討論了它。它表示AVFrame.data [0]包含每個像素的調色板索引,而AVFrame.data [1]包含一個1024字節的數組,用於定義每個8位索引的實際ARGB色彩值。 – 2010-07-27 13:19:35

1

有沒有人找到解決這個問題的方法?我在解碼端看到綠色視頻問題。也就是說,當我解碼傳入的PIX_FMT_YUV420數據包,然後將它們標記爲PIX_FMT_RGBA。

謝謝!

編輯: 綠色圖像可能是由於手臂優化回火。我用這個來解決我的情況的問題: http://ffmpeg-users.933282.n4.nabble.com/green-distorded-output-image-on-iPhone-td2231805.html

我猜的想法是不指定任何架構(該配置將你一個架構是未知的,但你可以繼續警告「使」反正)。這樣,手臂優化不會被使用。可能會有輕微的性能下降(如果有的話),但至少可以起作用! :)