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, ×tamp);
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, ×tamp);
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 }
|