Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can we get H.264 encoded video stream from iPhone Camera?

I am using following to get video sample buffer:

- (void) writeSampleBufferStream:(CMSampleBufferRef)sampleBuffer ofType:(NSString *)mediaType

Now my question is that how can I get h.264 encoded NSData from above sampleBuffer. Please suggest.

like image 484
Sukhpal Singh Avatar asked Jun 10 '13 06:06

Sukhpal Singh


People also ask

Does H 264 work on Iphone?

H. 264 is supported by all iPhones at the following settings (High Profile 4.2): 720p @ 24, 30, 48, 60, and 120 fps (NTSC) 720p @ 25, 30, 50, 60, and 120 fps (PAL)

What is h264 stream?

H. 264 is a well-known video compression standard for high-definition digital video. Also known as MPEG-4 Part 10 or Advanced Video Coding (MPEG-4 AVC), H. 264 is defined as a block-oriented, compensation-based video compression standard that defines multiple profiles (tools) and levels (max bitrates and resolutions).

Is H 264 high quality?

H. 264 was created to provide high-quality transmission of full-motion video with lower bandwidth requirements and lower latency traditional video standards, such as MPEG-2. H. 264 uses a very efficient codec that provides high-quality images and uses a minimal amount of bandwidth.


2 Answers

Update for 2017:

You can do streaming Video and Audio now by using the VideoToolbox API. Read the documentation here: VTCompressionSession

Original answer (from 2013):

Short: You can't, the sample buffer you receive is uncompressed.

Methods to get hardware accelerated h264 compression:

  • AVAssetWriter
  • AVCaptureMovieFileOutput

As you can see both write to a file, writing to a pipe does not work as the encoder updates header information after a frame or GOP has been fully written. So you better don't touch the file while the encoder writes to it as it does randomly rewrite header information. Without this header information the video file will not be playable (it updates the size field, so the first header written says the file is 0 bytes). Directly writing to a memory area is not supported currently. But you can open the encoded video-file and demux the stream to get to the h264 data (after the encoder has closed the file of course)

like image 123
Dunkelstern Avatar answered Sep 22 '22 08:09

Dunkelstern


You can only get raw video images in either BGRA or YUV color formats from AVFoundation. However, when you write those frames to an mp4 via AVAssetWriter, they will be encoded using H264 encoding.

A good example with code on how to do that is RosyWriter

Note that after each AVAssetWriter write, you will know that one complete H264 NAL was written to a mp4. You could write code that reads a complete H264 NAL after each write by AVAssetWriter, which is going to give you access to an H264 encoded frame. It might take a bit to get it right with decent speed, but it is doable( I did it successfully).

By the way, in order to successfully decode these encoded video frames, you will need H264 SPS and PPS information which is located in a different place in the mp4 file. In my case, I actually create couple of test mp4 files, and then manually extracted those out. Since those don't change, unless you change the H264 encoded specs, you can use them in your code.

Check my post to SPS values for H 264 stream in iPhone to see some of the SPS/PPS I used in my code.

Just a final note, in my case I had to stream h264 encoded frames to another endpoint for decoding/viewing; so my code had to do this fast. In my case, it was relatively fast; but eventually I switched to VP8 for encoding/decoding just because it was way faster because everything was done in memory without file reading/writing.

Good luck, and hopefully this info helps.

like image 30
Aki Avatar answered Sep 25 '22 08:09

Aki