Media Handle Management

Your application can manage various media handles with media tools.

The main features of the Media Tool API include:

  • Creating the media format handle

    You can set and get video or audio information such as average bps, bit, bit depth, channel, channel mask, mime type, sample rate, width, height and frame rate for each type using the media_format_h handle.

  • Creating the media packet handle

    You can set and get metadata using the created media_packet_h handle. However, some of the media_packet_h metadata such as pts, dts, duration, extra data, codec data, codec data size, rotation method and buffer flags are not filled after creating the media_packet_h handle.

The media_format_h handle is created by the caller, who can set and get the video or audio information. The media_format_h handle creates the media_packet_h handle and allocates the buffer. The caller can set and get the metadata with the media_packet_h handle.

The media_format_h handle has a specific design for increasing and decreasing its reference count.

Prerequisites

To enable your application to use the media tool functionality:

  • To use the media format handle of the Media Tool API (in mobile and wearable applications), include the <media_format.h> header file in your application:

    #include <media_format.h>
    
  • To use the media packet handle of the Media Tool API, include the <media_packet.h> header file in your application:

    #include <media_packet.h>
    

Managing the Media Format Handle

To manage the media format handle:

  1. Define a media_format_h variable for the media format handle, and pass the variable to the media_format_create() function, which returns the handle.

    To set the video information when creating the handle:

    media_format_h format;
    if (media_format_create(&format) == MEDIA_FORMAT_ERROR_NONE) {
        media_format_set_video_mime(format, MEDIA_FORMAT_H264_HP);
        media_format_set_video_width(format, 640);
        media_format_set_video_height(format, 480);
        media_format_set_video_avg_bps(format, 10000000);
        media_format_set_video_max_bps(format, 15000000);
    } else {
        printf("media_format_create() failed!");
    }
    

    To set the audio information, replace the media_format_set_video_XXX() functions with the relevant media_format_set_audio_XXX() functions in the above example code.

  2. To retrieve the video format information, use the media_format_get_video_info() function:

    media_format_h fmt;
    
    media_format_mimetype_e mime;
    int w;
    int h;
    int avg_bps;
    int max_bps;
    
    if (media_format_get_video_info(fmt, &mimetype, &w, &h, &avg_bps, &max_bps) == MEDIA_PACKET_ERROR_NONE)
        printf("media_format_get_video_info success! width = %d, height = %d", w, h);
    else
        print("media_format_get_video failed...");
    

    To retrieve the audio format information, use the media_format_get_audio_info() function.

Managing the Media Packet Handle

To manage the media packet handle:

  1. Define a media_packet_h variable for the media packet handle, and pass the variable to the appropriate media_packet_create_XXX() function (as the last parameter) with an existing media format handle (as the first parameter).

    After creating the media packet handle, call the media_format_unref() function for the media format handle. Because all functions that create a media packet handle increase the reference count of the media format handle, you must decrease the count.

    To reuse the media packet handle even after the media_packet_destroy() function is called, define a callback (the third last parameter of the media_packet_create_XXX() function), which is called when the handle is destroyed. Set the callback to return MEDIA_PACKET_REUSE.

    The following example codes show the different ways you create the media packet handle:

    • To create the handle and allocate a buffer into the heap or TBM surface, use the media_packet_create_alloc() function:

      {
          media_format_h fmt;
          media_packet_h packet;
      
          media_format_create(&fmt);
          media_format_set_video_mime(format, MEDIA_FORMAT_H264_HP);
          media_format_set_video_width(format, 640);
          media_format_set_video_height(format, 480);
          media_format_set_video_avg_bps(format, 10000000);
          media_format_set_video_max_bps(format, 15000000);
      
          /*
             MEDIA_FORMAT_H264_HP data type is MEDIA_FORMAT_ENCODED and the buffer
             is allocated into the heap
             If the data type is MEDIA_FORMAT_RAW,
             the buffer is allocated into the TBM surface
          */
          media_packet_create_alloc(fmt, _finalize_callback, fcb_data, &packet);
          media_format_unref(fmt);
      
          media_packet_destroy(packet);
      }
      
      int
      _finalize_callback(media_packet_h packet, int err, void* userdata)
      {
          return MEDIA_PACKET_REUSE;
      }
      
    • To create only the handle, use the media_packet_create() function:

      {
          media_format_h fmt;
          media_packet_h packet;
      
          media_format_create(&fmt);
          media_format_set_video_mime(format, MEDIA_FORMAT_H264_HP);
          media_format_set_video_width(format, 640);
          media_format_set_video_height(format, 480);
          media_format_set_video_avg_bps(format, 10000000);
          media_format_set_video_max_bps(format, 15000000);
      
          /* Only create the handle, do not allocate a buffer */
          media_packet_create(fmt, _finalize_callback, fcb_data, &packet);
          media_format_unref(fmt);
      }
      
      int
      _finalize_callback(media_packet_h packet, int err, void* userdata)
      {
          return MEDIA_PACKET_FINALIZE;
      }
      
    • To create the handle and store the TBM surface data, use the media_packet_create_from_tbm_surface() function:

      {
          media_format_h fmt;
          media_packet_h packet;
      
          media_format_create(&fmt);
          media_format_set_video_mime(format, MEDIA_FORMAT_RGBA);
          media_format_set_video_width(format, 128);
          media_format_set_video_height(format, 128);
          media_format_set_video_avg_bps(format, 10000000);
          media_format_set_video_avg_bps(format, 15000000);
      
          media_packet_create_from_tbm_surface(fmt, surface, _finalize_callback, fcb_data, &packet);
          media_format_unref(fmt);
      }
      
      int
      _finalize_callback(media_packet_h packet, int err, void* userdata)
      {
          return MEDIA_PACKET_FINALIZE;
      }
      
    • To create the handle with an already allocated external buffer, use the media_packet_create_from_external_memory() function:

      {
          media_format_h fmt;
          media_packet_h packet;
      
          media_format_create(&fmt);
          media_format_set_video_mime(format, MEDIA_FORMAT_H264_HP);
          media_format_set_video_width(format, 640);
          media_format_set_video_height(format, 480);
          media_format_set_video_avg_bps(format, 10000000);
          media_format_set_video_avg_bps(format, 15000000);
      
          media_packet_create_from_external_memory(fmt, mem_ptr, size, _finalize_callback, fcb_data, &packet);
          media_format_unref(fmt);
      }
      
      int
      _finalize_callback(media_packet_h packet, int err, void* userdata)
      {
          /* Do something */
      
          return MEDIA_PACKET_FINALIZE;
      }
      
  2. Set and get the metadata with the media packet handle:

    int ret = MEDIA_PACKET_ERROR_NONE;
    
    /* format1 already exists */
    
    media_packet_create_alloc(format1, NULL, NULL, &packet);
    
    ret = media_packet_set_duration(packet, duration);
    
    /* After media_packet_get_format(), use media_format_unref() */
    media_format_h tmp;
    media_packet_get_format(packet, &tmp);
    media_format_unref(tmp);
    
    /* Set previously created format2 to packet */
    /* After media_packet_set_format(), use media_format_unref() */
    media_packet_set_format(packet, format2);
    
    /*
       Packet format is format2
       If format2 ref_count is 1, format2 is free
       If format2 ref_count is bigger than 1, it is not free
    */
    media_packet_destroy(packet);
    

Reference Count Design

The following table describes the reference count design of the media_format_h handle.

Table: Media format handle reference count design

Function Reference count number Description
media_format_h fmt1, fmt2, tmp;
media_packet_h pkt1, pkt2;
media_format_create(&fmt1);
fmt1: 1 Define the media_format_h and media_packet_h handles.
Create the fmt1 handle and set the media_format_video_mime() or media_format_audio_mime() function.
media_packet_create(&pkt1, fmt1); fmt1: 2 After the media_packet_create() function, you must use the media_format_unref() function, because the media_packet_create() function increases the media_format_h reference count.
media_format_unref(fmt1); fmt1: 1 If the ref_count is 1, the fmt1 is currently owned by the pkt1 only.
media_packet_copy(pkt1, &pkt2); fmt1: 2 Copy the pkt1 metadata to pkt2, except the allocated buffer and buffer size. pkt2 refers to fmt1, and fmt1 ref_count is increased.
media_packet_get_format(pkt1, &tmp); fmt1: 3 fmt1 ref_count is increased by the media_packet_get_format() function.
media_format_set_video_mime(tmp, ...); fmt1: 3 If you try to modify the fmt1 data (call the media_format_set_video_mime() function) for fmt1 (=tmp), the ref_count is bigger than 1, and fmt1 cannot be modified.
To modify the fmt1 data, call the media_format_make_writable() function.
media_format_make_writable(tmp, &fmt2); fmt1: 2
fmt2: 1
If called, the tmp (fmt1) ref_count is decreased. Creates the fmt2 handle and copies the fmt1 data to fmt2.
media_format_set_video_mime(fmt2, ...); fmt1: 2
fmt2: 1
fmt2 ref_count is 1, which means that you can modify the fmt2 data.
media_packet_set_format(pkt2, fmt2); fmt1: 2
fmt2: 2
Set the modified fmt2 to the pkt2 handle. You must call the media_format_unref(fmt2) function.
media_format_unref(tmp); fmt1: 1
fmt2: 2
You must call this function because of the media_packet_get_format(pkt1, &tmp) function call.
media_format_unref(fmt2); fmt1: 1
fmt2: 1
You must call this function because of the media_packet_set_format(pkt2, fmt2) function call.
media_packet_destroy(pkt1); fmt1: 1 > finalize
fmt2: 1
If you destroy the pkt1 handle, the fmt1 ref_count is decreased. If the ref_count becomes 0, fmt1 is freed.
media_packet_destroy(pkt2); fmt1: 1 > finalize
fmt2: 0 > finalize
If you destroy the pkt2 handle, the fmt2 ref_count is decreased. If the ref_count becomes 0, fmt2 is freed.
  • Dependencies
    • Tizen 2.4 and Higher for Mobile
    • Tizen 2.3.1 and Higher for Wearable