| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -35,6 +35,7 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "libavutil/internal.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "libavutil/parseutils.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "libavutil/time.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "libavutil/imgutils.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "avdevice.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static const int avf_time_base = 1000000; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -892,6 +893,49 @@ fail: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return AVERROR(EIO); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int copy_cvpixelbuffer(AVFormatContext *s, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               CVPixelBufferRef image_buffer, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               AVPacket *pkt) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AVFContext *ctx = s->priv_data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int src_linesize[4]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const uint8_t *src_data[4]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int width  = CVPixelBufferGetWidth(image_buffer); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int height = CVPixelBufferGetHeight(image_buffer); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int status; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    memset(src_linesize, 0, sizeof(src_linesize)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    memset(src_data, 0, sizeof(src_data)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    status = CVPixelBufferLockBaseAddress(image_buffer, 0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (status != kCVReturnSuccess) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        av_log(s, AV_LOG_ERROR, "Could not lock base address: %d\n", status); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return AVERROR_EXTERNAL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (CVPixelBufferIsPlanar(image_buffer)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        size_t plane_count = CVPixelBufferGetPlaneCount(image_buffer); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        int i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        for(i = 0; i < plane_count; i++){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            src_linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(image_buffer, i); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            src_data[i] = CVPixelBufferGetBaseAddressOfPlane(image_buffer, i); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        src_linesize[0] = CVPixelBufferGetBytesPerRow(image_buffer); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        src_data[0] = CVPixelBufferGetBaseAddress(image_buffer); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    status = av_image_copy_to_buffer(pkt->data, pkt->size, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                     src_data, src_linesize, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                     ctx->pixel_format, width, height, 1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    CVPixelBufferUnlockBaseAddress(image_buffer, 0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return status; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AVFContext* ctx = (AVFContext*)s->priv_data; | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -903,7 +947,7 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        image_buffer = CMSampleBufferGetImageBuffer(ctx->current_frame); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (ctx->current_frame != nil) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            void *data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int status; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (av_new_packet(pkt, (int)CVPixelBufferGetDataSize(image_buffer)) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                return AVERROR(EIO); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -919,14 +963,12 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            pkt->stream_index  = ctx->video_stream_index; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            pkt->flags        |= AV_PKT_FLAG_KEY; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            CVPixelBufferLockBaseAddress(image_buffer, 0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            data = CVPixelBufferGetBaseAddress(image_buffer); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            memcpy(pkt->data, data, pkt->size); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            CVPixelBufferUnlockBaseAddress(image_buffer, 0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            status = copy_cvpixelbuffer(s, image_buffer, pkt); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            CFRelease(ctx->current_frame); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            ctx->current_frame = nil; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (status < 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                return status; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else if (ctx->current_audio_frame != nil) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(ctx->current_audio_frame); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int block_buffer_size         = CMBlockBufferGetDataLength(block_buffer); | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |