1

私はffmpegライブラリの助けを借りて1つの画像をエンコードしようとしています..実際にはライブビデオをエンコードしたいのですが、今のところ画像のエンコードから始めています..これがそのための私のコードです..

    av_register_all();
    avcodec_init();
    avcodec_register_all();
    avformat_alloc_context();

    AVCodec *codec;
    AVCodecContext *ctx= NULL;
    int out_size, size, outbuf_size;
    AVFrame *picture;
    uint8_t *outbuf;
    unsigned char *flvdata = malloc(sizeof(unsigned char) * 30);


    outbuf_size = 100000;
    outbuf = malloc(outbuf_size);


    printf("Video encoding\n");

    codec = avcodec_find_encoder(CODEC_ID_FLV1);
    if (!codec) {
            fprintf(stderr, "codec not found\n");
            exit(1);
    }

    ctx= avcodec_alloc_context();
    picture= avcodec_alloc_frame();


    ctx->width = 320;
    ctx->height = 240;
    ctx -> sample_rate = 11025;
    ctx -> time_base.den = 1000;
    ctx -> time_base.num = 23976;
    ctx -> codec_id = CODEC_ID_FLV1;
    ctx -> codec_type = CODEC_TYPE_VIDEO;
    ctx->pix_fmt = PIX_FMT_YUV420P;

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

    outbuf_size = 100000;
    outbuf = malloc(outbuf_size);
    size = ctx->width * ctx->height;

    AVFrame* outpic = avcodec_alloc_frame();
    int nbytes = avpicture_get_size(PIX_FMT_YUV420P, ctx->width, ctx->height);

    uint8_t* outbuffer = (uint8_t*)av_malloc(nbytes);

    fflush(stdout);

    int numBytes = avpicture_get_size(PIX_FMT_YUV420P, ctx->width, ctx->height);

    UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"0.jpg"]];
    CGImageRef newCgImage = [image CGImage];

    CGDataProviderRef dataProvider = CGImageGetDataProvider(newCgImage);
    CFDataRef bitmapData = CGDataProviderCopyData(dataProvider);
    long dataLength = CFDataGetLength(bitmapData);

    uint8_t *buffer = (uint8_t *)av_malloc(dataLength);
    buffer = (uint8_t *)CFDataGetBytePtr(bitmapData);

    for(int i = 0; i < dataLength; i++)
    {
            if((i + 1) % 16 == 1 && i != 1)
                    printf("\n");
            printf("%X\t",buffer[i]); // getting something different than the     actual hex value of the image
    }



    outpic -> pts = 0;        

    avpicture_fill((AVPicture*)picture, buffer, PIX_FMT_RGB8, ctx->width, ctx->height);

    avpicture_fill((AVPicture*)outpic, outbuffer, PIX_FMT_YUV420P, ctx->width, ctx->height);

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

    sws_scale(fooContext, picture->data, picture->linesize, 0, ctx->height, outpic->data, outpic->linesize);

    printf("abcdefghijklmnop");
    out_size = avcodec_encode_video(ctx, outbuf, outbuf_size, outpic);
    printf("\n\n out_size %d   outbuf_size %d",out_size,outbuf_size);

画像のサイズは 29 kb で、avcodec_encode_video は 20143 を返しています。それで正しいですか? つまり、エンコードしているため、サイズも小さくなるはずです...そして、その画像を16進モードで開いたところ、バッファ内とは異なるデータを取得しています(コードに示されているように)。バッファが正しいデータを取得していないと思います。右?誰でも私のコードを手伝ってもらえますか? 前もって感謝します...

4

1 に答える 1

0

自分の質問に答える...

outbuf_size を 200000 に増やした後、画像をエンコードできるようになりました。問題は、画像をエンコードするために大きなサイズのバッファが必要だったことです。これでエンコードの問題が解決しました。

しかし、エンコードされた画像が白黒であるため、別の問題があります。そしてカラー画像が欲しい。色付きの画像を取得するには、ピクセル形式をどのように設定すればよいか教えてください。助けてください...残り時間はほとんどありません。

前もって感謝します..

于 2012-05-16T21:46:21.463 に答える