Changeset 1368:ac122ded501e in mediastreamer2


Ignore:
Timestamp:
May 6, 2011 10:46:19 AM (2 years ago)
Author:
Guillaume Beraudo <guillaume.beraudo@…>
Branch:
default
Message:

Mac camera: plannar + incompatible format + leaks

  • Handle plannar pixels formats
  • Convert from incompatible hardware pixel formats to YUV420P
  • Fix pool memory leaks
  • Add an option to force output buffers from camera to a specific pixel format
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/qtcapture.m

    r1367 r1368  
    1111 
    1212struct v4mState; 
     13 
     14// Define != NULL to have QT Framework convert hardware device pixel format to another one. 
     15//static OSType forcedPixelFormat=kCVPixelFormatType_420YpCbCr8Planar; 
     16static OSType forcedPixelFormat=0; 
    1317 
    1418static MSPixFmt ostype_to_pix_fmt(OSType pixelFormat, bool printFmtName){ 
     
    3539@interface NsMsWebCam :NSObject 
    3640{ 
    37         NSAutoreleasePool *globalPool; 
    3841        QTCaptureDeviceInput *input; 
    3942        QTCaptureDecompressedVideoOutput * output; 
     
    8588                mblk_t *yuv_block = ms_yuv_buf_alloc(&pict, w, h); 
    8689 
    87                 //memset(pict.planes[0], 0, (w*h*3)/2); 
    8890                int p; 
    8991                for (p=0; p < numberOfPlanes; p++) { 
     
    9395                        uint8_t *dst_plane = pict.planes[p]; 
    9496                        uint8_t *src_plane = CVPixelBufferGetBaseAddressOfPlane(frame, p); 
    95                         ms_message("CVPixelBuffer %ix%i; Plane %i %ix%i (%i)", w, h, p, plane_width, plane_height, fullrow_width); 
     97//                      ms_message("CVPixelBuffer %ix%i; Plane %i %ix%i (%i)", w, h, p, plane_width, plane_height, fullrow_width); 
    9698                        int l; 
    9799                        for (l=0; l<plane_height; l++) { 
     
    122124        qinit(&rq); 
    123125        ms_mutex_init(&mutex,NULL); 
    124          
    125         globalPool = [[NSAutoreleasePool alloc] init]; 
    126126        session = [[QTCaptureSession alloc] init]; 
    127127        output = [[QTCaptureDecompressedVideoOutput alloc] init]; 
     
    129129        [output setDelegate: self]; 
    130130         
    131          
    132131        return self; 
    133132} 
     
    136135        [self stop]; 
    137136         
    138         if(session) 
    139         {                
     137        if (session) {           
    140138                [session release]; 
    141139                session = nil; 
    142140        } 
    143141                 
    144         if(input) 
    145         { 
     142        if (input) { 
    146143                [input release]; 
    147144                input = nil; 
    148145        } 
    149146         
    150         if(output) 
    151         { 
     147        if (output) { 
    152148                [output release]; 
    153149                output = nil; 
     
    156152        flushq(&rq,0); 
    157153 
    158         [globalPool drain]; 
    159154        ms_mutex_destroy(&mutex); 
    160155 
     
    176171} 
    177172 
    178 -(int) getPixFmt{ 
    179          
     173-(int) getPixFmt { 
     174        if (forcedPixelFormat != 0) { 
     175                MSPixFmt msfmt=ostype_to_pix_fmt(forcedPixelFormat, true); 
     176                ms_message("getPixFmt forced capture FMT: %i", msfmt); 
     177                return msfmt; 
     178        } 
     179 
    180180        QTCaptureDevice *device = [input device]; 
    181         if([device isOpen]) {    
     181        // Return the first pixel format of the hardware device compatible with mediastreamer 
     182        // Could be improved by choosing the best through all the formats supported by the hardware. 
     183        if([device isOpen]) { 
     184                NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];       
    182185                NSArray * array = [device formatDescriptions]; 
    183186         
     
    187190                        if ([desc mediaType] == QTMediaTypeVideo) { 
    188191                                UInt32 fmt = [desc formatType]; 
    189                                 MSPixFmt format = ostype_to_pix_fmt(fmt, true); 
    190                                 if (format != MS_PIX_FMT_UNKNOWN) return format; 
     192                                MSPixFmt msfmt = ostype_to_pix_fmt(fmt, true); 
     193                                if (msfmt != MS_PIX_FMT_UNKNOWN) { 
     194                                        [pool drain]; 
     195                                        return msfmt; 
     196                                } 
    191197                        } 
    192198                } 
     199                [pool drain]; 
    193200        } else { 
    194                 ms_warning("The camera wasn't opened"); 
     201                ms_error("The camera wasn't opened when asking for pixel format"); 
    195202        } 
    196         ms_warning("No format found, using MS_YUV420P pixel format"); 
     203 
     204        ms_warning("No compatible format found, using MS_YUV420P pixel format"); 
     205        // Configure the output to convert the uncompatible hardware pixel format to MS_YUV420P 
     206        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     207        NSDictionary *old_dic = [output pixelBufferAttributes]; 
     208        if ([[old_dic objectForKey:(id)kCVPixelBufferPixelFormatTypeKey] integerValue] != kCVPixelFormatType_420YpCbCr8Planar) { 
     209                NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys: 
     210                 [NSNumber numberWithInteger:[[old_dic objectForKey:(id)kCVPixelBufferWidthKey] integerValue]], (id)kCVPixelBufferWidthKey, 
     211                 [NSNumber numberWithInteger:[[old_dic objectForKey:(id)kCVPixelBufferHeightKey] integerValue]],(id)kCVPixelBufferHeightKey, 
     212                 [NSNumber numberWithInteger:kCVPixelFormatType_420YpCbCr8Planar], (id)kCVPixelBufferPixelFormatTypeKey, 
     213                  nil]; 
     214                  [output setPixelBufferAttributes:dic]; 
     215        } 
     216 
     217        [pool drain]; 
    197218        return MS_YUV420P; 
    198219} 
    199220 
    200 -(void) setName:(char*) name 
    201 { 
     221 
     222 
     223-(void) setName:(char*) name { 
    202224        NSError *error = nil; 
    203225        unsigned int i = 0; 
    204           
     226 
     227        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];       
    205228        QTCaptureDevice * device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo]; 
    206229         
     
    224247        else { 
    225248                ms_error("%s", [[error localizedDescription] UTF8String]); 
     249                [pool drain]; 
    226250                return; 
    227251        } 
     
    230254         
    231255        success = [session addInput:input error:&error]; 
    232         if (success) ms_message("Input added to session"); 
    233         else ms_error("%s", [[error localizedDescription] UTF8String]); 
     256        if (!success) ms_error("%s", [[error localizedDescription] UTF8String]); 
    234257         
    235258 
    236259        success = [session addOutput:output error:&error]; 
    237         if (success) ms_message("Output added to session"); 
    238         else ms_error("%s", [[error localizedDescription] UTF8String]); 
    239 } 
    240  
    241 -(void) setSize:(MSVideoSize) size 
    242 {        
    243         ms_message("Set size w=%i, h=%i", size.width, size.height); 
    244         NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys: 
    245          [NSNumber numberWithInteger:size.width], (id)kCVPixelBufferWidthKey, 
    246          [NSNumber numberWithInteger:size.height],(id)kCVPixelBufferHeightKey, 
    247 //       [NSNumber numberWithInteger:kCVPixelFormatType_420YpCbCr8Planar], (id)kCVPixelBufferPixelFormatTypeKey, // force pixel format to plannar 
    248                                                   nil]; 
     260        if (!success) ms_error("%s", [[error localizedDescription] UTF8String]); 
     261        [pool drain]; 
     262} 
     263 
     264-(void) setSize:(MSVideoSize) size {     
     265        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     266        NSDictionary *dic; 
     267        if (forcedPixelFormat != 0) { 
     268                ms_message("QTCapture set size w=%i, h=%i fmt=%i", size.width, size.height, forcedPixelFormat); 
     269                dic = [NSDictionary dictionaryWithObjectsAndKeys: 
     270                 [NSNumber numberWithInteger:size.width], (id)kCVPixelBufferWidthKey, 
     271                 [NSNumber numberWithInteger:size.height],(id)kCVPixelBufferHeightKey, 
     272                 [NSNumber numberWithInteger:forcedPixelFormat], (id)kCVPixelBufferPixelFormatTypeKey, // force pixel format to plannar 
     273                  nil]; 
     274        } else { 
     275                dic = [NSDictionary dictionaryWithObjectsAndKeys: 
     276                 [NSNumber numberWithInteger:size.width], (id)kCVPixelBufferWidthKey, 
     277                 [NSNumber numberWithInteger:size.height],(id)kCVPixelBufferHeightKey, 
     278                  nil]; 
     279        } 
    249280         
    250281        [output setPixelBufferAttributes:dic]; 
     282        [pool drain]; 
    251283} 
    252284 
     
    258290        size.height = MS_VIDEO_SIZE_QCIF_H; 
    259291         
    260         if(output) 
    261         { 
     292        if(output) { 
     293                NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    262294                NSDictionary * dic = [output pixelBufferAttributes]; 
    263                  
    264295                size.width = [[dic objectForKey:(id)kCVPixelBufferWidthKey] integerValue]; 
    265296                size.height = [[dic objectForKey:(id)kCVPixelBufferHeightKey] integerValue]; 
    266         } 
    267                 ms_message("get size w=%i, h=%i", size.width, size.height); 
     297                [pool drain]; 
     298        } 
    268299        return size; 
    269300} 
    270301 
    271 -(QTCaptureSession *) session 
    272 { 
     302-(QTCaptureSession *) session { 
    273303        return  session; 
    274304} 
    275305 
    276 -(queue_t*) rq 
    277 { 
     306-(queue_t*) rq { 
    278307        return &rq; 
    279308} 
    280309 
    281 -(ms_mutex_t *) mutex 
    282 { 
     310-(ms_mutex_t *) mutex { 
    283311        return &mutex; 
    284312} 
     
    299327        v4mState *s=ms_new0(v4mState,1); 
    300328        s->webcam= [[NsMsWebCam alloc] init]; 
    301 //      [s->webcam retain]; 
    302329        s->start_time=0; 
    303330        s->frame_count=-1; 
Note: See TracChangeset for help on using the changeset viewer.