modules/media/src/main/native/gstreamer/plugins/avcdecoder/avcdecoder.c

Print this page


   1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 295     int32_t deltaFlag = 0; // deltaFlag == 0 indicates an intra-frame, non-zero an inter-frame.
 296     if (NULL != frameInfo)
 297     {
 298         CFNumberRef timestampRef = CFDictionaryGetValue(frameInfo, CFSTR("timestamp"));
 299         if (timestampRef)
 300         {
 301             CFNumberGetValue(timestampRef, kCFNumberSInt64Type, &timestamp);
 302         }
 303         CFNumberRef deltaFlagRef = CFDictionaryGetValue(frameInfo, CFSTR("deltaFlag"));
 304         if (deltaFlagRef)
 305         {
 306             CFNumberGetValue(deltaFlagRef, kCFNumberSInt32Type, &deltaFlag);
 307         }
 308     }
 309 
 310     if (timestamp < decode->segment_start)
 311     {
 312         return;
 313     }
 314 


 315     if (isGap)
 316     {
 317         // Push a flagged, empty buffer it there is a problem.
 318 
 319         GstBuffer* buf = gst_buffer_new();
 320         GST_BUFFER_TIMESTAMP(buf) = timestamp;
 321         GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_GAP);
 322         g_queue_insert_sorted(decode->ordered_frames, buf, avcdecoder_buffer_compare, NULL);
 323     }
 324     else
 325     {
 326         // Push a valid buffer.
 327 
 328         CVBufferRetain(imageBuffer); // return value equals parameter
 329 
 330         GstPad* srcpad = decode->srcpad;
 331 
 332         size_t width = CVPixelBufferGetWidth(imageBuffer);
 333         size_t height = CVPixelBufferGetHeight(imageBuffer);
 334         size_t bytes_per_row = CVPixelBufferGetBytesPerRow(imageBuffer);
 335         if(!decode->is_stride_set)
 336         {
 337             GstStructure* caps_struct = gst_caps_get_structure(GST_PAD_CAPS(srcpad), 0);
 338             gst_structure_set(caps_struct, "line_stride", G_TYPE_INT, (int)bytes_per_row, NULL);
 339             decode->is_stride_set = TRUE;
 340         }
 341         gboolean is_buffer_enqueued = FALSE;
 342         if (kCVReturnSuccess == CVPixelBufferLockBaseAddress (imageBuffer, 0))
 343         {
 344             void* image_data = CVPixelBufferGetBaseAddress(imageBuffer);
 345             GstBuffer* buf;
 346             if (GST_FLOW_OK == gst_pad_alloc_buffer_and_set_caps (srcpad, 0, bytes_per_row*height,
 347                                                                   GST_PAD_CAPS(srcpad),
 348                                                                   &buf))
 349             {
 350                 guint8* buffer_data = GST_BUFFER_DATA (buf);
 351 
 352                 memcpy (buffer_data, image_data, GST_BUFFER_SIZE (buf));
 353                 GST_BUFFER_TIMESTAMP(buf) = timestamp;
 354 
 355                 g_queue_insert_sorted(decode->ordered_frames, buf, avcdecoder_buffer_compare, NULL);
 356                 is_buffer_enqueued = TRUE;
 357             }
 358 
 359             CVPixelBufferUnlockBaseAddress (imageBuffer, 0); // ignore return value
 360         }
 361 
 362         CVBufferRelease(imageBuffer);
 363 
 364         if (!is_buffer_enqueued)
 365         {
 366             GstBuffer* buf = gst_buffer_new();
 367             GST_BUFFER_TIMESTAMP(buf) = timestamp;
 368             GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_GAP);
 369             g_queue_insert_sorted(decode->ordered_frames, buf, avcdecoder_buffer_compare, NULL);
 370         }
 371     }
 372 






 373     GstBuffer* frame;
 374     GstFlowReturn ret = GST_FLOW_OK;
 375     while(ret == GST_FLOW_OK && !decode->is_flushing && NULL != (frame = g_queue_peek_head(decode->ordered_frames)))
 376     {
 377         GstClockTime ts = GST_BUFFER_TIMESTAMP(frame);
 378         if(GST_CLOCK_TIME_NONE == decode->previous_timestamp ||         // first frame
 379            ts <= decode->previous_timestamp + decode->timestamp_ceil || // frame is at next timestamp
 380            (0 == deltaFlag && ts < timestamp))                          // have newer I-frame
 381         {



 382             if(GST_BUFFER_FLAG_IS_SET(frame, GST_BUFFER_FLAG_GAP))
 383             {
 384                 // INLINE - gst_buffer_unref()
 385                 gst_buffer_unref (frame);
 386             }
 387             else
 388             {
 389                 if(decode->is_newsegment)
 390                 {
 391                     GST_BUFFER_FLAG_SET(frame, GST_BUFFER_FLAG_DISCONT);
 392                     decode->is_newsegment = FALSE;
 393                 }



 394                 ret = gst_pad_push(decode->srcpad, frame);

 395             }
 396             decode->previous_timestamp = ts;
 397             g_queue_pop_head(decode->ordered_frames);
 398         }
 399         else
 400         {
 401             break;
 402         }
 403     }


 404 }
 405 
 406 /*
 407  * GFunc used to unref GstBuffers in a queue.
 408  */
 409 static void
 410 avcdecoder_element_destroy(gpointer data, gpointer user_data)
 411 {
 412     if (NULL != data)
 413     {
 414         GstBuffer* buf = (GstBuffer*)data;
 415 
 416         // INLINE - gst_buffer_unref()
 417         gst_buffer_unref (buf);
 418     }
 419 }
 420 
 421 /**
 422  * Initialize the AvcDecoder structure. This should happen
 423  * only once, before decoding begins.
 424  */
 425 static void
 426 avcdecoder_state_init(AvcDecoder *decode)
 427 {
 428     decode->outputCallback = (VDADecoderOutputCallback*)avcdecoder_decoder_output_callback;
 429     decode->decoder = NULL;
 430     decode->is_initialized = FALSE;
 431     decode->is_newsegment = FALSE;
 432     decode->is_stride_set = FALSE;
 433     decode->frame_duration = GST_CLOCK_TIME_NONE;
 434     decode->ordered_frames = g_queue_new();

 435     decode->segment_start = 0;
 436 }
 437 
 438 /**
 439  * Reset the state of the AvcDecoder structure.
 440  */
 441 static void
 442 avcdecoder_state_reset(AvcDecoder *decode)
 443 {
 444     // Flush the decoder.
 445     if (NULL != decode->decoder)
 446     {
 447         OSStatus result = VDADecoderFlush (decode->decoder, 0);
 448 #if ENABLE_WARNINGS
 449         if (kVDADecoderNoErr != result)
 450         {
 451             g_warning ("Could not flush decoder: result code %d\n", (int)result);
 452         }
 453 #endif
 454     }
 455 


 456     // Unref all sorted buffers and clear the associated queue.
 457     if (NULL != decode->ordered_frames)
 458     {
 459         g_queue_foreach(decode->ordered_frames, avcdecoder_element_destroy, NULL);
 460         g_queue_clear(decode->ordered_frames);
 461     }
 462 
 463     decode->is_newsegment = FALSE;
 464     decode->segment_start = 0;


 465 }
 466 
 467 /**
 468  * Reset and then destroy the state of the AvcDecoder structure.
 469  */
 470 static void
 471 avcdecoder_state_destroy(AvcDecoder *decode)
 472 {
 473     // Reset the state.
 474     avcdecoder_state_reset(decode);
 475 
 476     // Release the VDADecoder.
 477     if (NULL != decode->decoder)
 478     {
 479         OSStatus result = VDADecoderDestroy (decode->decoder);
 480 #if ENABLE_WARNINGS
 481         if (kVDADecoderNoErr != result)
 482         {
 483             g_warning ("Could not destroy decoder: result code %d\n", (int)result);
 484         }
 485 #endif
 486         decode->decoder = NULL;
 487     }
 488 
 489     // Free the sorted queue.
 490     if (NULL != decode->ordered_frames)
 491     {
 492         g_queue_free(decode->ordered_frames);
 493         decode->ordered_frames = NULL;


 494     }
 495 }
 496 
 497 /*
 498  * Perform processing needed for state transitions.
 499  */
 500 static GstStateChangeReturn
 501 avcdecoder_change_state (GstElement* element, GstStateChange transition)
 502 {
 503     AvcDecoder *decode = AVCDECODER(element);
 504 
 505     switch(transition)
 506     {
 507         case GST_STATE_CHANGE_NULL_TO_READY:
 508             // Initialize the AvcDecoder structure.
 509             avcdecoder_state_init (decode);
 510             break;
 511         default:
 512             break;
 513     }


   1 /*
   2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 295     int32_t deltaFlag = 0; // deltaFlag == 0 indicates an intra-frame, non-zero an inter-frame.
 296     if (NULL != frameInfo)
 297     {
 298         CFNumberRef timestampRef = CFDictionaryGetValue(frameInfo, CFSTR("timestamp"));
 299         if (timestampRef)
 300         {
 301             CFNumberGetValue(timestampRef, kCFNumberSInt64Type, &timestamp);
 302         }
 303         CFNumberRef deltaFlagRef = CFDictionaryGetValue(frameInfo, CFSTR("deltaFlag"));
 304         if (deltaFlagRef)
 305         {
 306             CFNumberGetValue(deltaFlagRef, kCFNumberSInt32Type, &deltaFlag);
 307         }
 308     }
 309 
 310     if (timestamp < decode->segment_start)
 311     {
 312         return;
 313     }
 314 
 315     GstBuffer* buf = NULL;
 316     
 317     if (isGap)
 318     {
 319         // Push a flagged, empty buffer it there is a problem.
 320 
 321         buf = gst_buffer_new();
 322         GST_BUFFER_TIMESTAMP(buf) = timestamp;
 323         GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_GAP);

 324     }
 325     else
 326     {
 327         // Push a valid buffer.
 328 
 329         CVBufferRetain(imageBuffer); // return value equals parameter
 330 
 331         GstPad* srcpad = decode->srcpad;
 332 
 333         size_t width = CVPixelBufferGetWidth(imageBuffer);
 334         size_t height = CVPixelBufferGetHeight(imageBuffer);
 335         size_t bytes_per_row = CVPixelBufferGetBytesPerRow(imageBuffer);
 336         if(!decode->is_stride_set)
 337         {
 338             GstStructure* caps_struct = gst_caps_get_structure(GST_PAD_CAPS(srcpad), 0);
 339             gst_structure_set(caps_struct, "line_stride", G_TYPE_INT, (int)bytes_per_row, NULL);
 340             decode->is_stride_set = TRUE;
 341         }

 342         if (kCVReturnSuccess == CVPixelBufferLockBaseAddress (imageBuffer, 0))
 343         {
 344             void* image_data = CVPixelBufferGetBaseAddress(imageBuffer);

 345             if (GST_FLOW_OK == gst_pad_alloc_buffer_and_set_caps (srcpad, 0, bytes_per_row*height,
 346                                                                   GST_PAD_CAPS(srcpad),
 347                                                                   &buf))
 348             {
 349                 guint8* buffer_data = GST_BUFFER_DATA (buf);
 350 
 351                 memcpy (buffer_data, image_data, GST_BUFFER_SIZE (buf));
 352                 GST_BUFFER_TIMESTAMP(buf) = timestamp;



 353             }
 354 
 355             CVPixelBufferUnlockBaseAddress (imageBuffer, 0); // ignore return value
 356         }
 357 
 358         CVBufferRelease(imageBuffer);
 359 
 360         if (!buf)
 361         {
 362             buf = gst_buffer_new();
 363             GST_BUFFER_TIMESTAMP(buf) = timestamp;
 364             GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_GAP);

 365         }
 366     }
 367 
 368     // the callback might be called from several threads
 369     // need to synchronize ordered_frames queue access
 370     g_mutex_lock(decode->mutex);
 371 
 372     g_queue_insert_sorted(decode->ordered_frames, buf, avcdecoder_buffer_compare, NULL);
 373     
 374     GstBuffer* frame;
 375     GstFlowReturn ret = GST_FLOW_OK;
 376     while(ret == GST_FLOW_OK && !decode->is_flushing && NULL != (frame = g_queue_peek_head(decode->ordered_frames)))
 377     {
 378         GstClockTime ts = GST_BUFFER_TIMESTAMP(frame);
 379         if(GST_CLOCK_TIME_NONE == decode->previous_timestamp ||         // first frame
 380            ts <= decode->previous_timestamp + decode->timestamp_ceil || // frame is at next timestamp
 381            (0 == deltaFlag && ts < timestamp))                          // have newer I-frame
 382         {
 383             decode->previous_timestamp = ts;
 384             g_queue_pop_head(decode->ordered_frames);
 385 
 386             if(GST_BUFFER_FLAG_IS_SET(frame, GST_BUFFER_FLAG_GAP))
 387             {
 388                 // INLINE - gst_buffer_unref()
 389                 gst_buffer_unref (frame);
 390             }
 391             else
 392             {
 393                 if(decode->is_newsegment)
 394                 {
 395                     GST_BUFFER_FLAG_SET(frame, GST_BUFFER_FLAG_DISCONT);
 396                     decode->is_newsegment = FALSE;
 397                 }
 398 
 399                 // it's better not to call gst_pad_push under mutex to avoid deadlocks
 400                 g_mutex_unlock(decode->mutex);
 401                 ret = gst_pad_push(decode->srcpad, frame);
 402                 g_mutex_lock(decode->mutex);
 403             }


 404         }
 405         else
 406         {
 407             break;
 408         }
 409     }
 410     
 411     g_mutex_unlock(decode->mutex);
 412 }
 413 
 414 /*
 415  * GFunc used to unref GstBuffers in a queue.
 416  */
 417 static void
 418 avcdecoder_element_destroy(gpointer data, gpointer user_data)
 419 {
 420     if (NULL != data)
 421     {
 422         GstBuffer* buf = (GstBuffer*)data;
 423 
 424         // INLINE - gst_buffer_unref()
 425         gst_buffer_unref (buf);
 426     }
 427 }
 428 
 429 /**
 430  * Initialize the AvcDecoder structure. This should happen
 431  * only once, before decoding begins.
 432  */
 433 static void
 434 avcdecoder_state_init(AvcDecoder *decode)
 435 {
 436     decode->outputCallback = (VDADecoderOutputCallback*)avcdecoder_decoder_output_callback;
 437     decode->decoder = NULL;
 438     decode->is_initialized = FALSE;
 439     decode->is_newsegment = FALSE;
 440     decode->is_stride_set = FALSE;
 441     decode->frame_duration = GST_CLOCK_TIME_NONE;
 442     decode->ordered_frames = g_queue_new();
 443     decode->mutex = g_mutex_new();
 444     decode->segment_start = 0;
 445 }
 446 
 447 /**
 448  * Reset the state of the AvcDecoder structure.
 449  */
 450 static void
 451 avcdecoder_state_reset(AvcDecoder *decode)
 452 {
 453     // Flush the decoder.
 454     if (NULL != decode->decoder)
 455     {
 456         OSStatus result = VDADecoderFlush (decode->decoder, 0);
 457 #if ENABLE_WARNINGS
 458         if (kVDADecoderNoErr != result)
 459         {
 460             g_warning ("Could not flush decoder: result code %d\n", (int)result);
 461         }
 462 #endif
 463     }
 464 
 465     g_mutex_lock(decode->mutex);
 466 
 467     // Unref all sorted buffers and clear the associated queue.
 468     if (NULL != decode->ordered_frames)
 469     {
 470         g_queue_foreach(decode->ordered_frames, avcdecoder_element_destroy, NULL);
 471         g_queue_clear(decode->ordered_frames);
 472     }
 473 
 474     decode->is_newsegment = FALSE;
 475     decode->segment_start = 0;
 476 
 477     g_mutex_unlock(decode->mutex);
 478 }
 479 
 480 /**
 481  * Reset and then destroy the state of the AvcDecoder structure.
 482  */
 483 static void
 484 avcdecoder_state_destroy(AvcDecoder *decode)
 485 {
 486     // Reset the state.
 487     avcdecoder_state_reset(decode);
 488 
 489     // Release the VDADecoder.
 490     if (NULL != decode->decoder)
 491     {
 492         OSStatus result = VDADecoderDestroy (decode->decoder);
 493 #if ENABLE_WARNINGS
 494         if (kVDADecoderNoErr != result)
 495         {
 496             g_warning ("Could not destroy decoder: result code %d\n", (int)result);
 497         }
 498 #endif
 499         decode->decoder = NULL;
 500     }
 501 
 502     // Free the sorted queue.
 503     if (NULL != decode->ordered_frames)
 504     {
 505         g_queue_free(decode->ordered_frames);
 506         decode->ordered_frames = NULL;
 507         g_mutex_free(decode->mutex);
 508         decode->mutex = NULL;
 509     }
 510 }
 511 
 512 /*
 513  * Perform processing needed for state transitions.
 514  */
 515 static GstStateChangeReturn
 516 avcdecoder_change_state (GstElement* element, GstStateChange transition)
 517 {
 518     AvcDecoder *decode = AVCDECODER(element);
 519 
 520     switch(transition)
 521     {
 522         case GST_STATE_CHANGE_NULL_TO_READY:
 523             // Initialize the AvcDecoder structure.
 524             avcdecoder_state_init (decode);
 525             break;
 526         default:
 527             break;
 528     }