Frame analysis from .mov using ffmpeg

I am trying to parse H.264 frames from a .mov file. I think I came to the conclusion that mov.c from the AVFormat part of FFMPEG is the way to go. But mov.c is ~ 2600 lines next to unregistered code. I am looking for examples of using FFMPEG, especially for parsing the structure of any type of file. it does not matter if it is MPEG4 or Quicktime Movie, as they are very similar in structure.

if there are no existing examples (I cannot find them), maybe someone used it and can give me a couple of lines of code or explain how to get started?

What I'm trying to do: I use AVCaptureSession to capture samples from the camcorder, these samples are then encoded in H264 and written to a file using AVAssetsWriter, AVAssetsWriterInput and AVAssetsWriterInputPixelBufferAdaptor. The reason is that I cannot access the hardware encoding of H264 directly, as Apple will not allow this. What I now need ( I think I'm not sure ) parsing:

" mdat " - atom (movie data may be more than one than I think) from the .mov file. then " vide " - an atom, and then in the form of an atom (there can be more than one video sample). I think there will be several atoms, which I consider to be frames. they will be of type avc1 (this is the type for H264). Please correct me in this, because I am quite sure that I have not yet received all this correctly .

Now my question is how I will parse individual frames. I read the documentation and looked at the iFrameExtractor (which is not very useful as it decodes frames). I think I understood correctly when I should use mov.c from FFMPEG-AVFormat, but I'm not sure.

: :

  • init iFrameExtractor, .mov .

  • :

    AVPacket packet;
    av_read_frame(pFormatCtx, &packet);
    NSData *frame;
    if(packet.stream_index == videoStream){
        frame = [NSData dataWithBytes:packet.data length:packet.size];
    }
    videoStream++;
    av_free_packet(&packet);
    return frame;
    

i NSOperation, . EXC_BAD_ACC, - ? . EXC _..., NSData* frame, (, ) . ( EXC_BAD_ACC )

+5
3

, mov.

-(NSData *)nextFrame {
    AVPacket packet;
    NSData *frame = nil;

    while(!frame && av_read_frame(pFormatCtx, &packet)>=0) {

        if(packet.stream_index == streamNo) {
            frame = [[[NSData alloc] initWithBytes:packet.data length:packet.size] autorelease];
        }
        av_free_packet(&packet);
    }
    return frame;
}

, av_read_frame , . , "" , .

AVFormatContext * pFormatCtx AVCodecContext * pCodecCtx (, , ):

    AVCodec *pCodec;

    // Register all formats and codecs
    av_register_all();

    // Open video file
    if(avformat_open_input(&pFormatCtx, [moviePath cStringUsingEncoding:NSASCIIStringEncoding], NULL, NULL)!=0)
        goto initError; // Couldn't open file

    // Retrieve stream information
    if(avformat_find_stream_info(pFormatCtx,NULL)<0)
        goto initError; // Couldn't find stream information

    // Find the video stream
    streamNo = -1;
    for(int i=0; i<pFormatCtx->nb_streams; i++){
        if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            streamNo = i;
            break;
        }
    }
    if(streamNo == -1)
        goto initError; // Didn't find a video stream

    // Get a pointer to the codec context for the video stream
    pCodecCtx=pFormatCtx->streams[streamNo]->codec;

    // Find the decoder for the video stream
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
        goto initError; // Codec not found

    // Open codec
    if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)
        goto initError; // Could not open codec

    return self;

initError:
    NSLog(@"initError in VideoFrameExtractor");
    [self release];
    return nil;

, - .

+1

libavcodec/libavformat . , , DoSomethingWithTheImage(), .

0
0

All Articles