2010-05-28 9 views
0

일련의 CGImages에서 비디오를 디스크에 기록하는 데 사용하는 Objective-C 클래스가 있습니다 (Obj-C에만 해당하는 것은 아니지만). (픽셀 데이터를 얻기 위해 맨 위에서 사용하는 코드는 Apple에서 바로 제공됩니다 : http://developer.apple.com/mac/library/qa/qa2007/qa1509.html). 성공적으로 코덱과 컨텍스트를 만듭니다. EXC_BAD_ACCESS를 얻을 때 avcodec_encode_video가 될 때까지 모든 것이 잘 진행됩니다. 나는 이것이 간단한 수정이어야한다고 생각하지만, 나는 어디서 잘못 될지 알 수 없다.avcodec_encode_video를 호출 할 때 EXC_BAD_ACCESS

나는 간결함을 검사하는 데 몇 가지 오류가 발생했습니다. 'c'는 성공적으로 생성 된 AVCodecContext *입니다.

-(void)addFrame:(CGImageRef)img 
{ 
    CFDataRef bitmapData = CGDataProviderCopyData(CGImageGetDataProvider(img)); 
    long dataLength = CFDataGetLength(bitmapData); 
    uint8_t* picture_buff = (uint8_t*)malloc(dataLength); 
    CFDataGetBytes(bitmapData, CFRangeMake(0, dataLength), picture_buff); 

    AVFrame *picture = avcodec_alloc_frame(); 
    avpicture_fill((AVPicture*)picture, picture_buff, c->pix_fmt, c->width, c->height); 

    int outbuf_size = avpicture_get_size(c->pix_fmt, c->width, c->height); 
    uint8_t *outbuf = (uint8_t*)av_malloc(outbuf_size); 

    out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); // ERROR occurs here 
    printf("encoding frame %3d (size=%5d)\n", i, out_size); 
    fwrite(outbuf, 1, out_size, f); 

    CFRelease(bitmapData); 
    free(picture_buff); 
    free(outbuf); 
    av_free(picture); 
    i++; 
} 

나는 수십 번 밟았습니다. 다음은 몇 가지 수는 ...이다

  1. 데이터 길이 = 408960
  2. picture_buff = 0x5c85000
  3. picture-> 데이터 [0] = 0x5c85000 - 내가 그 avpicture_fill이 일을 의미하기 위해 수행하는 ...
  4. outbuf_size = 408960

그리고 나서 avcodec_encode_video에서 EXC_BAD_ACCESS를 얻습니다. 관련성이 있는지는 잘 모르지만 대부분이 코드는 api-example.c에서 제공합니다. Snow Leopard에서 armv6/armv7 용으로 컴파일 한 XCode를 사용하고 있습니다.

도움을 위해 미리 감사드립니다.

+0

혹시이 문제를 해결 했습니까? – skorulis

답변

0

나는 정확한 오류를 가리 키도록 여기에 충분한 정보를 가지고,하지만 난 문제가 입력 영상이 기대) (avcodec_encode_video보다 적은 데이터가 포함되어 있다고 생각 : 일부 포인터와 숫자를 설정)

avpicture_fill (AVFrame 구조의 값. 아무것도 복사하지 않으며 버퍼가 충분히 큰지 (버퍼 크기가 전달되지 않기 때문에) 큰지 검사하지 않습니다. 은 (는 FFmpeg 소스에서 복사)이 같은 수행합니다 너비와 높이가 변수 "C"합니다 (AVCodecContext, 나는 가정)에서 전달되는

size = picture->linesize[0] * height; 
    picture->data[0] = ptr; 
    picture->data[1] = picture->data[0] + size; 
    picture->data[2] = picture->data[1] + size2; 
    picture->data[3] = picture->data[1] + size2 + size2; 

참고 때문에 실제 크기보다 클 수 있습니다 입력 프레임의

너비/높이가 좋지만 입력 프레임의 픽셀 형식이 avpicture_fill()에 전달 된 것과 다를 수 있습니다. (픽셀 형식은 입력과 다를 수있는 AVCodecContext에서도 가져옵니다). 예를 들어, c-> pix_fmt가 RGBA이고 입력 버퍼가 YUV420 형식 (또는 양립성 YCbCr 인 iPhone의 경우) 일 경우 입력 버퍼의 크기는 width * height * 1.5이지만 avpicture_fill()은 width * height * 4의 크기입니다.

입/출력 지오메트리 및 픽셀 형식을 확인하면 오류의 원인이 될 수 있습니다. 도움이되지 않으면 먼저 i386 용으로 컴파일해야한다고 제안합니다. FFMPEG를 iPhone 용으로 컴파일하는 것은 어렵습니다.

+0

답변 해 주셔서 감사합니다. 테스트와 마찬가지로 picture_buff을 10 배 더 크게 만들었으며 동일한 오류가 발생합니다. 복사 한 소스에 PIX_FMT_YUV420P (평면) 이미지가 필요합니다. 이는 4 가지 포인터를 설정하는 이유입니다. 각 채널의 시작을 가리키고 있습니다. 나는, 내 경우, C-> pix_fmt = PIX_FMT_RGB24에 나는 또한 체크 할 것을 언급해야 같아요! 을 경우 (CGImageGetWidth (IMG) = C-> 폭 || CGImageGetHeight (IMG) = C- > 높이) { NSLog (@ "프레임이 영화 크기와 일치하지 않습니다."); 반환; } 도움이 될만한 다른 정보가 있습니까? –

+0

또는 - 도와주세요 : –

+0

글쎄, 그 버그는 여기에 없지만 코덱 초기화 코드에서 - 디버깅하기가 훨씬 더 어렵다고 생각합니다. (무엇을 설정하지 않았습니까? AVCodecContext의 일부 매개 변수. avcodec.h의 주석을 확인하여 누락 된 부분을 확인해야합니다. 도움이되지 않으면 ffmpeg 코드를 디버깅하는 것 외에는 아무 것도 남지 않았습니다 ... (실제로 사소한 오류가 발생하면 도움이됩니다!) avcodec_encode_video()에서 충돌이 발생합니까? 해당 함수에서 충돌하는 것이 하나 밖에 없기 때문에 : codecContext-> codec가 NULL 인 경우 (av_register_all()을 호출 했습니까?) – gyim

0

인코딩하려는 코덱이 RGB 색상 공간을 지원합니까? 인코딩하기 전에 libswscale을 사용하여 I420으로 변환해야 할 수도 있습니다. 어떤 코덱을 사용하고 있습니까? 코덱 컨텍스트를 초기화하는 코드를 게시 할 수 있습니까?

+0

H.264는 RGB를 지원합니다. MPEG4는 그렇지 않습니다. 나는 둘 다 시도했다. 지금은 비디오를 여는 코드에서 컨텍스트와 코덱을 직접 가져옵니다. 이것이 작동하지 않아야하는 이유가 있습니까? 리더 : http://github.com/jefftimesten/Unlogo/blob/master/Classes/VideoFrameExtractor.m 작성자 : http://github.com/jefftimesten/Unlogo/blob/master/Classes/VideoMaker.m –

관련 문제