Advertisement
hejmus

Untitled

Jun 21st, 2012
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.59 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2012 Broadcom Europe Ltd
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements.  See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership.
  7. * The ASF licenses this file to You under the Apache License, Version 2.0
  8. * (the "License"); you may not use this file except in compliance with
  9. * the License.  You may obtain a copy of the License at
  10. *
  11. *     http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. *
  20. * Video deocode demo using OpenMAX IL though the ilcient helper library
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #include "bcm_host.h"
  28. #include "ilclient.h"
  29.  
  30. static int video_decode_test(char *filename)
  31. {
  32.    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
  33.    OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
  34.    COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *video_render = NULL, *clock = NULL;
  35.    COMPONENT_T *list[5];
  36.    TUNNEL_T tunnel[4];
  37.    ILCLIENT_T *client;
  38.    FILE *in;
  39.    int status = 0;
  40.    unsigned char *data = NULL;
  41.    unsigned int data_len = 0;
  42.    int find_start_codes = 0;
  43.    int packet_size = 16<<10;  
  44.  
  45.    memset(list, 0, sizeof(list));
  46.    memset(tunnel, 0, sizeof(tunnel));
  47.  
  48.    if((in = fopen(filename, "rb")) == NULL)
  49.       return -2;
  50.  
  51.    if((client = ilclient_init()) == NULL)
  52.    {
  53.       fclose(in);
  54.       return -3;
  55.    }
  56.  
  57.    if(OMX_Init() != OMX_ErrorNone)
  58.    {
  59.       ilclient_destroy(client);
  60.       fclose(in);
  61.       return -4;
  62.    }
  63.  
  64.    if(find_start_codes && (data = malloc(packet_size+4)) == NULL)
  65.    {
  66.       status = -16;
  67.       if(OMX_Deinit() != OMX_ErrorNone)
  68.          status = -17;
  69.       ilclient_destroy(client);
  70.       fclose(in);
  71.       return status;
  72.    }
  73.    // create video_decode
  74.    if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0)
  75.       status = -14;
  76.    list[0] = video_decode;
  77.  
  78.    // create video_render
  79.    if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
  80.       status = -14;
  81.    list[1] = video_render;
  82.  
  83.    // create clock
  84.    if(status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0)
  85.       status = -14;
  86.    list[2] = clock;
  87.  
  88.    memset(&cstate, 0, sizeof(cstate));
  89.    cstate.nSize = sizeof(cstate);
  90.    cstate.nVersion.nVersion = OMX_VERSION;
  91.    cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
  92.    cstate.nWaitMask = 1;
  93.    if(clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone)
  94.       status = -13;
  95.  
  96.    // create video_scheduler
  97.    if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0)
  98.       status = -14;
  99.    list[3] = video_scheduler;
  100.  
  101.    set_tunnel(tunnel, video_decode, 131, video_scheduler, 10);
  102.    set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90);
  103.    set_tunnel(tunnel+2, clock, 80, video_scheduler, 12);
  104.  
  105.    // setup clock tunnel first
  106.    if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0)
  107.       status = -15;
  108.    else
  109.       ilclient_change_component_state(clock, OMX_StateExecuting);
  110.  
  111.    if(status == 0)
  112.       ilclient_change_component_state(video_decode, OMX_StateIdle);
  113.  
  114.    memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
  115.    format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
  116.    format.nVersion.nVersion = OMX_VERSION;
  117.    format.nPortIndex = 130;
  118.    format.eCompressionFormat = OMX_VIDEO_CodingAVC;
  119.  
  120.    if(status == 0 &&
  121.       OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone &&
  122.       ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0)
  123.    {
  124.       OMX_BUFFERHEADERTYPE *buf;
  125.       int port_settings_changed = 0;
  126.       int first_packet = 1;
  127.  
  128.       ilclient_change_component_state(video_decode, OMX_StateExecuting);
  129.  
  130.       while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL)
  131.       {
  132.          // feed data and wait until we get port settings changed
  133.          unsigned char *dest = find_start_codes ? data + data_len : buf->pBuffer;
  134.  
  135.          data_len += fread(dest, 1, packet_size+(find_start_codes*4)-data_len, in);
  136.  
  137.          if(port_settings_changed == 0 &&
  138.             ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) ||
  139.              (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1,
  140.                                                        ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0)))
  141.          {
  142.             port_settings_changed = 1;
  143.  
  144.             if(ilclient_setup_tunnel(tunnel, 0, 0) != 0)
  145.             {
  146.                status = -7;
  147.                break;
  148.             }
  149.  
  150.             ilclient_change_component_state(video_scheduler, OMX_StateExecuting);
  151.  
  152.             // now setup tunnel to video_render
  153.             if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0)
  154.             {
  155.                status = -12;
  156.                break;
  157.             }
  158.            
  159.             ilclient_change_component_state(video_render, OMX_StateExecuting);
  160.          }
  161.          if(!data_len)
  162.             break;
  163.  
  164.          if(find_start_codes)
  165.          {
  166.             int i, start = -1, len = 0;
  167.             int max_len = data_len > packet_size ? packet_size : data_len;
  168.             for(i=2; i<max_len; i++)
  169.             {
  170.                if(data[i-2] == 0 && data[i-1] == 0 && data[i] == 1)
  171.                {
  172.                   len = 3;
  173.                   start = i-2;
  174.  
  175.                   // check for 4 byte start code
  176.                   if(i > 2 && data[i-3] == 0)
  177.                   {
  178.                      len++;
  179.                      start--;
  180.                   }
  181.  
  182.                   break;
  183.                }
  184.             }
  185.  
  186.             if(start == 0)
  187.             {
  188.                // start code is next, so just send that
  189.                buf->nFilledLen = len;
  190.             }
  191.             else if(start == -1)
  192.             {
  193.                // no start codes seen, send the first block
  194.                buf->nFilledLen = max_len;
  195.             }
  196.             else
  197.             {
  198.                // start code in the middle of the buffer, send up to the code
  199.                buf->nFilledLen = start;
  200.             }
  201.  
  202.             memcpy(buf->pBuffer, data, buf->nFilledLen);
  203.             memmove(data, data + buf->nFilledLen, data_len - buf->nFilledLen);
  204.             data_len -= buf->nFilledLen;
  205.          }
  206.          else
  207.          {
  208.             buf->nFilledLen = data_len;
  209.             data_len = 0;
  210.          }
  211.  
  212.          buf->nOffset = 0;
  213.          if(first_packet)
  214.          {
  215.             buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
  216.             first_packet = 0;
  217.          }
  218.          else
  219.             buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
  220.  
  221.          if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone)
  222.          {
  223.             status = -6;
  224.             break;
  225.          }
  226.          
  227.       }
  228.  
  229.       buf->nFilledLen = 0;
  230.       buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;
  231.      
  232.       if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone)
  233.          status = -20;
  234.      
  235.       // wait for EOS from render
  236.       ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,
  237.                               ILCLIENT_BUFFER_FLAG_EOS, 10000);
  238.      
  239.       // need to flush the renderer to allow video_decode to disable its input port
  240.       ilclient_flush_tunnels(tunnel, 0);
  241.  
  242.       ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);
  243.    }
  244.  
  245.    fclose(in);
  246.  
  247.    ilclient_disable_tunnel(tunnel);
  248.    ilclient_disable_tunnel(tunnel+1);
  249.    ilclient_disable_tunnel(tunnel+2);
  250.    ilclient_teardown_tunnels(tunnel);
  251.  
  252.    ilclient_state_transition(list, OMX_StateIdle);
  253.    ilclient_state_transition(list, OMX_StateLoaded);
  254.  
  255.    ilclient_cleanup_components(list);
  256.  
  257.    OMX_Deinit();
  258.  
  259.    ilclient_destroy(client);
  260.    return status;
  261. }
  262.  
  263. int main (int argc, char **argv)
  264. {
  265.    if (argc < 2) {
  266.       printf("Usage: %s <filename>\n", argv[0]);
  267.       exit(1);
  268.    }
  269.    bcm_host_init();
  270.    return video_decode_test(argv[1]);
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement