--- /dev/null
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
--- /dev/null
+PROGRAMS = hello_video2_tizen hello_video2_normal
+CXXFLAGS = -DSTANDALONE -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -DTARGET_POSIX -D_LINUX -DPIC -D_REENTRANT -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -U_FORTIFY_SOURCE -DHAVE_LIBOPENMAX=2 -DOMX -DOMX_SKIP64BIT -ftree-vectorize -pipe -DUSE_EXTERNAL_OMX -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST -DUSE_VCHIQ_ARM -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -fPIC -ftree-vectorize -pipe -Wall -Werror -O0 -g2
+LDFLAGS = -L/opt/vc/lib -lopenmaxil -lpthread -lvcos -lvchiq_arm -lbcm_host -ltbm
+
+all: $(PROGRAMS)
+
+clean:
+ rm -f $(PROGRAMS)
+
+.PHONY: all clean
--- /dev/null
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "hello_video2_normal.h"
+
+#define OMX_INIT_STRUCTURE(a) \
+ memset(&(a), 0, sizeof(a)); \
+ (a).nSize = sizeof(a); \
+ (a).nVersion.nVersion = OMX_VERSION; \
+ (a).nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
+ (a).nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
+ (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \
+ (a).nVersion.s.nStep = OMX_VERSION_STEP
+
+static pthread_t thread_t1;
+
+static void *__port_settings_changed_thread(void *data)
+{
+ hello_video2 *hello_video = (hello_video2*)data;
+
+ while (1) {
+ OMWaitForXPortSettingsChanged();
+
+ hello_video->port_settings_changed();
+ hello_video->fill_buffer();
+ }
+
+ return NULL;
+}
+
+OMX_ERRORTYPE hello_video2::Init()
+{
+ OMX_ERRORTYPE ErrorCode = OMX_Init();
+
+ if (ErrorCode == OMX_ErrorNone) {
+ return ErrorCode;
+ }
+ else {
+ printf("Err:%s\n", OMX_strerror(ErrorCode));
+
+ return ErrorCode;
+ }
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::DeInit()
+{
+ OMX_ERRORTYPE ErrorCode = OMX_Deinit();
+
+ if (ErrorCode == OMX_ErrorNone) {
+ return ErrorCode;
+ }
+ else {
+ printf("Err:%s\n", OMX_strerror(ErrorCode));
+
+ return ErrorCode;
+ }
+};
+
+/******************************************************************************/
+
+const char * hello_video2::OMX_strerror(OMX_ERRORTYPE ErrorCode)
+{
+ switch (ErrorCode)
+ {
+ case OMX_ErrorNone:
+ return "Operation completed succesfully.";
+ case OMX_ErrorInsufficientResources:
+ return "There were insufficient resources to perform the requested operation.";
+ case OMX_ErrorUndefined:
+ return "There was an error, but the caues of the error could not be determined.";
+ case OMX_ErrorInvalidComponentName:
+ return "The component name string was not valid.";
+ case OMX_ErrorComponentNotFound:
+ return "No component with the specified name string was found";
+ case OMX_ErrorInvalidComponent:
+ return "The component specified did not have a \"OMX_ComponentInit\" or \"OMX_ComponentDeInit\" entry point.";
+ case OMX_ErrorBadParameter:
+ return "One or more parameters were invalid.";
+ case OMX_ErrorNotImplemented:
+ return "The requested function is not implemented.";
+ case OMX_ErrorUnderflow:
+ return "The buffer was emptied before the next buffer was ready.";
+ case OMX_ErrorOverflow:
+ return "The buffer was not available whe it was needed.";
+ case OMX_ErrorHardware:
+ return "The hardware failed to respond as expected.";
+ case OMX_ErrorInvalidState:
+ return "The component is in the state OMX_StateInvalid.";
+ case OMX_ErrorStreamCorrupt:
+ return "Stream is found to be corrupt.";
+ case OMX_ErrorPortsNotCompatible:
+ return "Ports being connected are not compatible.";
+ case OMX_ErrorResourcesLost:
+ return "Resources allocated to an idle component have been lost resulting in the component returning to the loaded state.";
+ case OMX_ErrorNoMore:
+ return "No more indices can be enumerated.";
+ case OMX_ErrorVersionMismatch:
+ return "The component detected a version mismatch.";
+ case OMX_ErrorNotReady:
+ return "The component is not ready to return data at this time.";
+ case OMX_ErrorTimeout:
+ return "There was a timeout that occured.";
+ case OMX_ErrorSameState:
+ return "The component cannot complete the transition to state it is already in.";
+ case OMX_ErrorResourcesPreempted:
+ return "Resources allocated to an executing or paused component have been preempted. Returning to Idle state.";
+ case OMX_ErrorPortUnresponsiveDuringAllocation:
+ return "During a call to UseBuffer() port became unresponsive.";
+ case OMX_ErrorPortUnresponsiveDuringDeallocation:
+ return "During a call to FreeBuffer() port became unresponsive.";
+ case OMX_ErrorPortUnresponsiveDuringStop:
+ return "During stopping of a port, it became unresponsive.";
+ case OMX_ErrorIncorrectStateTransition:
+ return "Attempting a state transition that is not allowed.";
+ case OMX_ErrorIncorrectStateOperation:
+ return "Attempting a state transition that is not allowed.";
+ case OMX_ErrorUnsupportedSetting:
+ return "The values encapsulated in the parameter or config structure are not supported.";
+ case OMX_ErrorUnsupportedIndex:
+ return "The parameter or config indicated by the given index is not supported.";
+ case OMX_ErrorBadPortIndex:
+ return "The port index supplied is incorrect.";
+ case OMX_ErrorPortUnpopulated:
+ return "The port has lost one or more of its buffers an it thus unpopulated.";
+ case OMX_ErrorDynamicResourcesUnavailable:
+ return "Component suspended due to inability to acquire dynamic resources.";
+ case OMX_ErrorMbErrorsInFrame:
+ return "Corrupted frame.";
+ case OMX_ErrorFormatNotDetected:
+ return "OMX_ErrorFormatNotDetected";
+ case OMX_ErrorSeperateTablesUsed:
+ return "Separate table information is being used.";
+ default:
+ return "Error not defined. Error is: ";
+ }
+}
+
+/******************************************************************************/
+
+unsigned int hello_video2::FindAllNALu(unsigned char *source, unsigned int size, NALu *table)
+{
+ unsigned int num = 0;
+ for (unsigned int i = 0; i < size; i++)
+ {
+#if 0
+ if (source[i] == 0x00)
+ if (source[i + 1] == 0x00)
+ if (source[i + 2] == 0x00)
+#else
+ if ((source[i] + source[i + 1] + source[i + 2]) == 0x00)
+#endif
+ if (source[i + 3] == 0x01)
+ {
+// fprintf(stderr, "%s[%d]i(%d)\n", __func__, __LINE__, i);
+ table[num] = NALu(i, size - i, ((unsigned int)(source[i + 4] & 31)));
+
+ if (num != 0)
+ {
+ table[num - 1].size = i - table[num - 1].pos;
+ };
+
+ num++;
+ };
+ };
+
+ return num;
+};
+
+
+/******************************************************************************/
+
+OMX_ERRORTYPE eventHandler(OMX_HANDLETYPE hComp, OMX_PTR pAppD,
+ OMX_EVENTTYPE event, OMX_U32 data1,
+ OMX_U32 data2, OMX_PTR eventData)
+{
+ switch(event) {
+ case OMX_EventCmdComplete:
+ switch (data1) {
+ case OMX_CommandStateSet:
+ OMXWakeUp((OMX_STATETYPE) data2);
+ break;
+ case OMX_CommandFlush:
+ break;
+ case OMX_CommandPortDisable:
+ if (data2 == 130) phello_video2->input_port_def.bEnabled = OMX_FALSE;
+ if (data2 == 131) phello_video2->output_port_def.bEnabled = OMX_FALSE;
+ break;
+ case OMX_CommandPortEnable:
+ if (data2 == 130) phello_video2->input_port_def.bEnabled = OMX_TRUE;
+ if (data2 == 131) phello_video2->output_port_def.bEnabled = OMX_TRUE;
+ break;
+ case OMX_CommandMarkBuffer:
+ break;
+ default:
+ break;
+ }
+ break;
+ case OMX_EventError:
+ fprintf(stderr, "Err:%s[%d]%s\n.", __func__, __LINE__, hello_video2::OMX_strerror((OMX_ERRORTYPE) data1));
+ break;
+ case OMX_EventPortSettingsChanged:
+ fprintf(stderr, "Port settings changed...\n");
+ OMXWakeupPortSettingsChanged();
+ break;
+ case OMX_EventBufferFlag:
+ case OMX_EventResourcesAcquired:
+ case OMX_EventDynamicResourcesAvailable:
+ case OMX_EventMark:
+ break;
+ default:
+ break;
+ }
+
+ return OMX_ErrorNone;
+};
+
+/******************************************************************************/
+
+OMX_ERRORTYPE bufferEmptied(OMX_HANDLETYPE hComp, OMX_PTR pAppD,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ phello_video2->input_buffer_usage |= *((unsigned int *)buffer->pAppPrivate);
+
+ OMXWakeUpEmpty();
+ return OMX_ErrorNone;
+};
+
+/******************************************************************************/
+
+OMX_ERRORTYPE bufferFilled(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_BUFFERHEADERTYPE *buffer)
+{
+ phello_video2->output_buffer_usage |= *((unsigned int *)buffer->pAppPrivate);
+// fprintf(stderr, "******** callback:bufferFilled, buffer->nFilledLen=%d\n", buffer->nFilledLen);
+
+ OMXWakeUpFilled();
+
+ if (buffer->nFilledLen == 0) {
+ phello_video2->fill_buffer();
+
+ return OMX_ErrorNone;
+ }
+
+ phello_video2->fill_buffer(pAppD, buffer);
+
+ return OMX_ErrorNone;
+};
+
+/******************************************************************************/
+
+hello_video2::hello_video2()
+{
+ bcm_host_init();
+
+ hello_video2::Init();
+
+ input_buffer_usage = 0;
+ output_buffer_usage = 0;
+ input_buffer_number[0] = 0;
+ output_buffer_number[0] = 0;
+ phello_video2 = this;
+
+ callback.EventHandler = &eventHandler;
+ callback.EmptyBufferDone = &bufferEmptied;
+ callback.FillBufferDone = &bufferFilled;
+
+ memset(&input_port_def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ input_port_def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+ input_port_def.nVersion.nVersion = OMX_VERSION;
+ input_port_def.nPortIndex = 130;
+
+ memset(&output_port_def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ output_port_def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+ output_port_def.nVersion.nVersion = OMX_VERSION;
+ output_port_def.nPortIndex = 131;
+
+ OMX_ERRORTYPE ErrorCode = OMX_GetHandle(&component, (OMX_STRING)"OMX.broadcom.video_decode", NULL, &callback);
+
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ OMX_FreeHandle(component);
+ component = NULL;
+
+ return;
+ }
+
+ get_port_parameters();
+
+ set_port_parameters();
+
+ ErrorCode = OMX_SendCommand(component, OMX_CommandPortDisable, OMX_ALL, NULL);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ }
+
+ ErrorCode = OMX_SendCommand(component, OMX_CommandStateSet, OMX_StateIdle ,NULL);
+
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ return;
+ }
+
+ OMXWaitForState(OMX_StateIdle);
+}
+
+/******************************************************************************/
+
+hello_video2::~hello_video2()
+{
+}
+
+/******************************************************************************/
+
+const char* hello_video2::dump_compression_video_format(OMX_VIDEO_CODINGTYPE c) {
+ static char *f = NULL;
+ switch(c) {
+ case OMX_VIDEO_CodingUnused: return "not used";
+ case OMX_VIDEO_CodingAutoDetect: return "autodetect";
+ case OMX_VIDEO_CodingMPEG2: return "MPEG2";
+ case OMX_VIDEO_CodingH263: return "H.263";
+ case OMX_VIDEO_CodingMPEG4: return "MPEG4";
+ case OMX_VIDEO_CodingWMV: return "Windows Media Video";
+ case OMX_VIDEO_CodingRV: return "RealVideo";
+ case OMX_VIDEO_CodingAVC: return "H.264/AVC";
+ case OMX_VIDEO_CodingMJPEG: return "Motion JPEG";
+ case OMX_VIDEO_CodingVP6: return "VP6";
+ case OMX_VIDEO_CodingVP7: return "VP7";
+ case OMX_VIDEO_CodingVP8: return "VP8";
+ case OMX_VIDEO_CodingYUV: return "Raw YUV video";
+ case OMX_VIDEO_CodingSorenson: return "Sorenson";
+ case OMX_VIDEO_CodingTheora: return "OGG Theora";
+ case OMX_VIDEO_CodingMVC: return "H.264/MVC";
+
+ default:
+ if (f == NULL) {
+ f = (char*)calloc(64, sizeof(char));
+ if(f == NULL) {
+ fprintf(stderr, "Failed to allocate memory");
+ exit(-1);
+ }
+ }
+ snprintf(f, 64 * sizeof(char) - 1, "format type 0x%08x", c);
+ return f;
+ }
+}
+
+/******************************************************************************/
+
+const char* hello_video2::dump_compression_image_format(OMX_IMAGE_CODINGTYPE c) {
+ static char *f = NULL;
+ switch(c) {
+ case OMX_IMAGE_CodingUnused: return "Value when format is N/A";
+ case OMX_IMAGE_CodingAutoDetect: return "Auto detection of image format";
+ case OMX_IMAGE_CodingJPEG: return "JPEG/JFIF image format";
+ case OMX_IMAGE_CodingJPEG2K: return "JPEG 2000 image format";
+ case OMX_IMAGE_CodingEXIF: return "EXIF image format";
+ case OMX_IMAGE_CodingTIFF: return "TIFF image format";
+ case OMX_IMAGE_CodingGIF: return "Graphics image format";
+ case OMX_IMAGE_CodingPNG: return "PNG image format";
+ case OMX_IMAGE_CodingLZW: return "LZW image format";
+ case OMX_IMAGE_CodingBMP: return "Windows Bitmap format";
+ case OMX_IMAGE_CodingKhronosExtensions: return "Reserved region for introducing Khronos Standard Extensions";
+ case OMX_IMAGE_CodingVendorStartUnused: return "Reserved region for introducing Vendor Extensions";
+ case OMX_IMAGE_CodingTGA: return "TGA format";
+ case OMX_IMAGE_CodingPPM: return "PPM format";
+ default:
+ if (f == NULL) {
+ f = (char*)calloc(64, sizeof(char));
+ if(f == NULL) {
+ fprintf(stderr, "Failed to allocate memory");
+ exit(-1);
+ }
+ }
+ snprintf(f, 64 * sizeof(char) - 1, "format type 0x%08x", c);
+ return f;
+ }
+}
+
+/******************************************************************************/
+
+const char* hello_video2::dump_color_format(OMX_COLOR_FORMATTYPE c) {
+ static char *f = NULL;
+ switch(c) {
+ case OMX_COLOR_FormatUnused: return "OMX_COLOR_FormatUnused: not used";
+ case OMX_COLOR_FormatMonochrome: return "OMX_COLOR_FormatMonochrome";
+ case OMX_COLOR_Format8bitRGB332: return "OMX_COLOR_Format8bitRGB332";
+ case OMX_COLOR_Format12bitRGB444: return "OMX_COLOR_Format12bitRGB444";
+ case OMX_COLOR_Format16bitARGB4444: return "OMX_COLOR_Format16bitARGB4444";
+ case OMX_COLOR_Format16bitARGB1555: return "OMX_COLOR_Format16bitARGB1555";
+ case OMX_COLOR_Format16bitRGB565: return "OMX_COLOR_Format16bitRGB565";
+ case OMX_COLOR_Format16bitBGR565: return "OMX_COLOR_Format16bitBGR565";
+ case OMX_COLOR_Format18bitRGB666: return "OMX_COLOR_Format18bitRGB666";
+ case OMX_COLOR_Format18bitARGB1665: return "OMX_COLOR_Format18bitARGB1665";
+ case OMX_COLOR_Format19bitARGB1666: return "OMX_COLOR_Format19bitARGB1666";
+ case OMX_COLOR_Format24bitRGB888: return "OMX_COLOR_Format24bitRGB888";
+ case OMX_COLOR_Format24bitBGR888: return "OMX_COLOR_Format24bitBGR888";
+ case OMX_COLOR_Format24bitARGB1887: return "OMX_COLOR_Format24bitARGB1887";
+ case OMX_COLOR_Format25bitARGB1888: return "OMX_COLOR_Format25bitARGB1888";
+ case OMX_COLOR_Format32bitBGRA8888: return "OMX_COLOR_Format32bitBGRA8888";
+ case OMX_COLOR_Format32bitARGB8888: return "OMX_COLOR_Format32bitARGB8888";
+ case OMX_COLOR_FormatYUV411Planar: return "OMX_COLOR_FormatYUV411Planar";
+ case OMX_COLOR_FormatYUV411PackedPlanar: return "OMX_COLOR_FormatYUV411PackedPlanar: Planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_FormatYUV420Planar: return "OMX_COLOR_FormatYUV420Planar: Planar YUV, 4:2:0 (I420)";
+ case OMX_COLOR_FormatYUV420PackedPlanar: return "OMX_COLOR_FormatYUV420PackedPlanar: Planar YUV, 4:2:0 (I420), planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_FormatYUV420SemiPlanar: return "OMX_COLOR_FormatYUV420SemiPlanar, Planar YUV, 4:2:0 (NV12), U and V planes interleaved with first U value";
+ case OMX_COLOR_FormatYUV422Planar: return "OMX_COLOR_FormatYUV422Planar";
+ case OMX_COLOR_FormatYUV422PackedPlanar: return "OMX_COLOR_FormatYUV422PackedPlanar: Planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_FormatYUV422SemiPlanar: return "OMX_COLOR_FormatYUV422SemiPlanar";
+ case OMX_COLOR_FormatYCbYCr: return "OMX_COLOR_FormatYCbYCr";
+ case OMX_COLOR_FormatYCrYCb: return "OMX_COLOR_FormatYCrYCb";
+ case OMX_COLOR_FormatCbYCrY: return "OMX_COLOR_FormatCbYCrY";
+ case OMX_COLOR_FormatCrYCbY: return "OMX_COLOR_FormatCrYCbY";
+ case OMX_COLOR_FormatYUV444Interleaved: return "OMX_COLOR_FormatYUV444Interleaved";
+ case OMX_COLOR_FormatRawBayer8bit: return "OMX_COLOR_FormatRawBayer8bit";
+ case OMX_COLOR_FormatRawBayer10bit: return "OMX_COLOR_FormatRawBayer10bit";
+ case OMX_COLOR_FormatRawBayer8bitcompressed: return "OMX_COLOR_FormatRawBayer8bitcompressed";
+ case OMX_COLOR_FormatL2: return "OMX_COLOR_FormatL2";
+ case OMX_COLOR_FormatL4: return "OMX_COLOR_FormatL4";
+ case OMX_COLOR_FormatL8: return "OMX_COLOR_FormatL8";
+ case OMX_COLOR_FormatL16: return "OMX_COLOR_FormatL16";
+ case OMX_COLOR_FormatL24: return "OMX_COLOR_FormatL24";
+ case OMX_COLOR_FormatL32: return "OMX_COLOR_FormatL32";
+ case OMX_COLOR_FormatYUV420PackedSemiPlanar: return "OMX_COLOR_FormatYUV420PackedSemiPlanar: Planar YUV, 4:2:0 (NV12), planes fragmented when a frame is split in multiple buffers, U and V planes interleaved with first U value";
+ case OMX_COLOR_FormatYUV422PackedSemiPlanar: return "OMX_COLOR_FormatYUV422PackedSemiPlanar: Planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_Format18BitBGR666: return "OMX_COLOR_Format18BitBGR666";
+ case OMX_COLOR_Format24BitARGB6666: return "OMX_COLOR_Format24BitARGB6666";
+ case OMX_COLOR_Format24BitABGR6666: return "OMX_COLOR_Format24BitABGR6666";
+ case OMX_COLOR_Format32bitABGR8888: return "OMX_COLOR_Format32bitABGR8888";
+ case OMX_COLOR_Format8bitPalette: return "OMX_COLOR_Format8bitPalette";
+ case OMX_COLOR_FormatYUVUV128: return "OMX_COLOR_FormatYUVUV128";
+ case OMX_COLOR_FormatRawBayer12bit: return "OMX_COLOR_FormatRawBayer12bit";
+ case OMX_COLOR_FormatBRCMEGL: return "OMX_COLOR_FormatBRCMEGL";
+ case OMX_COLOR_FormatBRCMOpaque: return "OMX_COLOR_FormatBRCMOpaque";
+ case OMX_COLOR_FormatYVU420PackedPlanar: return "OMX_COLOR_FormatYVU420PackedPlanar";
+ case OMX_COLOR_FormatYVU420PackedSemiPlanar: return "OMX_COLOR_FormatYVU420PackedSemiPlanar";
+ default:
+ if (f == NULL) {
+ f = (char*)calloc(64, sizeof(char));
+ if(f == NULL) {
+ fprintf(stderr, "Failed to allocate memory");
+ exit(-1);
+ }
+ }
+ snprintf(f, 64 * sizeof(char) - 1, "format type 0x%08x", c);
+ return f;
+ }
+}
+
+/******************************************************************************/
+void hello_video2::dump_portdef(OMX_PARAM_PORTDEFINITIONTYPE* portdef) {
+ fprintf(stderr, "Port %d is %s, %s, buffers wants:%d needs:%d, size:%d, pop:%d, aligned:%d",
+ portdef->nPortIndex,
+ (portdef->eDir == OMX_DirInput ? "input" : "output"),
+ (portdef->bEnabled == OMX_TRUE ? "enabled" : "disabled"),
+ portdef->nBufferCountActual,
+ portdef->nBufferCountMin,
+ portdef->nBufferSize,
+ portdef->bPopulated,
+ portdef->nBufferAlignment);
+
+ OMX_VIDEO_PORTDEFINITIONTYPE *viddef = &portdef->format.video;
+ OMX_IMAGE_PORTDEFINITIONTYPE *imgdef = &portdef->format.image;
+ switch(portdef->eDomain) {
+ case OMX_PortDomainVideo:
+ fprintf(stderr, "Video type:\n"
+ "\tWidth:\t\t%d\n"
+ "\tHeight:\t\t%d\n"
+ "\tStride:\t\t%d\n"
+ "\tSliceHeight:\t%d\n"
+ "\tBitrate:\t%d\n"
+ "\tFramerate:\t%.02f\n"
+ "\tError hiding:\t%s\n"
+ "\tCodec:\t\t%s\n"
+ "\tColor:\t\t%s\n",
+ viddef->nFrameWidth,
+ viddef->nFrameHeight,
+ viddef->nStride,
+ viddef->nSliceHeight,
+ viddef->nBitrate,
+ ((float)viddef->xFramerate / (float)65536),
+ (viddef->bFlagErrorConcealment == OMX_TRUE ? "yes" : "no"),
+ dump_compression_video_format(viddef->eCompressionFormat),
+ dump_color_format(viddef->eColorFormat));
+ break;
+ case OMX_PortDomainImage:
+ fprintf(stderr, "Image type:\n"
+ "\tWidth:\t\t%d\n"
+ "\tHeight:\t\t%d\n"
+ "\tStride:\t\t%d\n"
+ "\tSliceHeight:\t%d\n"
+ "\tError hiding:\t%s\n"
+ "\tCodec:\t\t%s\n"
+ "\tColor:\t\t%s\n",
+ imgdef->nFrameWidth,
+ imgdef->nFrameHeight,
+ imgdef->nStride,
+ imgdef->nSliceHeight,
+ (imgdef->bFlagErrorConcealment == OMX_TRUE ? "yes" : "no"),
+ dump_compression_image_format(imgdef->eCompressionFormat),
+ dump_color_format(imgdef->eColorFormat));
+ break;
+ default:
+ break;
+ }
+}
+
+/******************************************************************************/
+
+void hello_video2::dump_port(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL dumpformats) {
+ OMX_ERRORTYPE r;
+ OMX_PARAM_PORTDEFINITIONTYPE portdef;
+
+ OMX_INIT_STRUCTURE(portdef);
+ portdef.nPortIndex = nPortIndex;
+ if((r = OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &portdef)) != OMX_ErrorNone) {
+ fprintf(stderr, "Failed to get port definition for port %d:%s\n", nPortIndex, OMX_strerror(r));
+ }
+ dump_portdef(&portdef);
+ if(dumpformats) {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE portformat;
+ OMX_INIT_STRUCTURE(portformat);
+ portformat.nPortIndex = nPortIndex;
+ portformat.nIndex = 0;
+ r = OMX_ErrorNone;
+ fprintf(stderr, "Port %d supports these video formats:", nPortIndex);
+ while(r == OMX_ErrorNone) {
+ if((r = OMX_GetParameter(hComponent, OMX_IndexParamVideoPortFormat, &portformat)) == OMX_ErrorNone) {
+ fprintf(stderr, "\t%s, compression: %s", dump_color_format(portformat.eColorFormat), dump_compression_video_format(portformat.eCompressionFormat));
+ portformat.nIndex++;
+ }
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+/******************************************************************************/
+OMX_STATETYPE hello_video2::get_state()
+{
+ ErrorCode = OMX_GetState(component, &component_state);
+
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Error while obtaining component state. %s\n", OMX_strerror(ErrorCode));
+ }
+
+ return component_state;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::set_state(OMX_STATETYPE nState)
+{
+ OMX_SendCommand(component, OMX_CommandStateSet, nState, NULL);
+ OMXWaitForState(nState);
+ return OMX_ErrorNone;
+};
+
+OMX_ERRORTYPE hello_video2::block_until_port_changed(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL bEnabled) {
+ OMX_ERRORTYPE r;
+ OMX_PARAM_PORTDEFINITIONTYPE portdef;
+ OMX_U32 i = 0;
+
+ OMX_INIT_STRUCTURE(portdef);
+ portdef.nPortIndex = nPortIndex;
+
+ while(i++ == 0 || portdef.bEnabled != bEnabled) {
+ if((r = OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &portdef)) != OMX_ErrorNone) {
+ fprintf(stderr, "Failed to get port definition:%s\n", OMX_strerror(r));
+ }
+ if(portdef.bEnabled != bEnabled) {
+ usleep(10000);
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::decode_frame(unsigned char * data, unsigned int size)
+{
+ OMX_ERRORTYPE ErrorCode = OMX_ErrorNone;
+
+ if (input_port_def.bEnabled == OMX_FALSE) {
+ fprintf(stderr, "Check:%s[%d] input_port_def.bEnabled is OMX_FALSE\n", __func__, __LINE__);
+ ErrorCode = OMX_SendCommand(component, OMX_CommandPortEnable, 130, NULL);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "Err:%s\n", OMX_strerror(ErrorCode));
+ return OMX_ErrorNone;
+ }
+ block_until_port_changed(component, input_port_def.nPortIndex, OMX_TRUE);
+ }
+
+ if (input_buffer_number[0] == 0)
+ {
+ ErrorCode = prepare_input_buffers(20);
+ if (ErrorCode != OMX_ErrorNone) {
+ return OMX_ErrorNone;
+ }
+ }
+
+ if (get_state() != OMX_StateExecuting) {
+ ErrorCode = set_state(OMX_StateExecuting);
+ }
+
+ if (size <= input_port_def.nBufferSize) {
+ OMX_BUFFERHEADERTYPE * iBuffer = get_free_input_buffer();
+ memcpy(iBuffer->pBuffer, data, size);
+ iBuffer->nOffset = 0;
+ iBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+ iBuffer->nFilledLen = size;
+ input_buffer_usage ^= *((unsigned int *)iBuffer->pAppPrivate);
+ OMX_EmptyThisBuffer(component, iBuffer);
+ }
+ else {
+ NALu nalu[1000];
+ unsigned int nSize = FindAllNALu(data, size, nalu);
+ for (unsigned int i = 0; i < nSize; i ++)
+ {
+ OMX_BUFFERHEADERTYPE * iBuffer = get_free_input_buffer();
+ void * pStart = &data[nalu[i].pos];
+ memcpy(iBuffer->pBuffer, pStart, nalu[i].size);
+ iBuffer->nOffset = 0;
+ iBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+ iBuffer->nFilledLen = nalu[i].size;
+ input_buffer_usage ^= *((unsigned int *)iBuffer->pAppPrivate);
+ OMX_EmptyThisBuffer(component, iBuffer);
+ fprintf(stderr, "OMX_EmptyThisBuffer:%d/%d\n", i+1, nSize);
+ usleep(50000);
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+void *write_yuv_dump_to_file_thread(void *data) {
+ DUMP_FILE_INFO *dump_file_info;
+
+ dump_file_info = (DUMP_FILE_INFO*)data;
+
+ phello_video2->_write_yuv_dump_to_file(dump_file_info->file_path, *dump_file_info->data, dump_file_info->size);
+
+ free(*dump_file_info->data);
+ free(data);
+
+ return NULL;
+}
+
+OMX_ERRORTYPE hello_video2::write_yuv_dump_to_file(const char *file_path, void *data, int size)
+{
+ pthread_t thread_t;
+ char *mdata;
+ DUMP_FILE_INFO *box_info;
+
+ box_info = (DUMP_FILE_INFO*)malloc(sizeof(DUMP_FILE_INFO));
+
+ mdata = (char*)malloc(size);
+ if (!mdata) {
+ return OMX_ErrorNone;
+ }
+
+ box_info->data = (void**)&mdata;
+ strcpy(box_info->file_path, file_path);
+ box_info->size = size;
+ memcpy(*box_info->data, data, size);
+
+ pthread_create(&thread_t, NULL, write_yuv_dump_to_file_thread, (void*)box_info);
+
+ fill_buffer();
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE hello_video2::_write_yuv_dump_to_file(const char *file_path, void *data, int size)
+{
+ FILE *fd;
+ int remainder;
+ int written;
+
+ fd = fopen(file_path, "wb");
+ if (!fd) {
+ fprintf(stderr, "open failed:%s\n", file_path);
+ return OMX_ErrorNone;
+ }
+
+ remainder = size;
+ while (remainder) {
+ written = fwrite(data, 1, remainder, fd);
+ remainder -= written;
+ }
+ fflush(fd);
+ fclose(fd);
+
+ fprintf(stderr, "saved yuv:%s\n", file_path);
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::fill_buffer(OMX_PTR pAppD, OMX_BUFFERHEADERTYPE *buffer)
+{
+ static int number = 0;
+ char file_path[128];
+
+ mkdir("/var/yuv", 0777);
+ sprintf(file_path, "/var/yuv/1280x544_yuv420p-%04d.yuv", number++);
+ write_yuv_dump_to_file(file_path, buffer->pBuffer, buffer->nFilledLen);//output_port_def.nBufferSize);
+
+ return OMX_ErrorNone;
+}
+OMX_ERRORTYPE hello_video2::fill_buffer()
+{
+ OMX_BUFFERHEADERTYPE *out_buffer;
+
+ out_buffer = get_free_output_buffer();
+ OMX_FillThisBuffer(component, out_buffer);
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::port_settings_changed()
+{
+ fprintf(stderr, "PortSettingsChanged...\n");
+ if (output_buffer_header[0] != NULL) {
+ OMX_SendCommand(component, OMX_CommandPortDisable, output_port_def.nPortIndex, NULL);
+ block_until_port_changed(component, output_port_def.nPortIndex, OMX_FALSE);
+ for (unsigned int i = 0; i < output_port_def.nBufferCountActual; ++i) {
+ OMX_FreeBuffer(component, 131, output_buffer_header[i]);
+ output_buffer_header[i] = NULL;
+ }
+ } else {
+ OMX_SendCommand(component, OMX_CommandPortDisable, output_port_def.nPortIndex, NULL);
+ block_until_port_changed(component, output_port_def.nPortIndex, OMX_FALSE);
+ }
+
+ get_port_parameters();
+
+ ErrorCode = OMX_SendCommand(component, OMX_CommandPortEnable, output_port_def.nPortIndex, NULL);
+ block_until_port_changed(component, output_port_def.nPortIndex, OMX_TRUE);
+
+ get_port_parameters();
+
+ output_buffer_usage = 0;
+ prepare_output_buffers(output_port_def.nBufferCountActual);
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::get_port_parameters()
+{
+ ErrorCode = OMX_ErrorNone;
+
+ ErrorCode = OMX_GetParameter(component, OMX_IndexParamPortDefinition, &input_port_def);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ };
+
+ ErrorCode = OMX_GetParameter(component, OMX_IndexParamPortDefinition, &output_port_def);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::set_port_parameters()
+{
+ ErrorCode = OMX_ErrorNone;
+ OMX_VIDEO_PARAM_PORTFORMATTYPE ovPort, ivPort;
+ memset(&ovPort, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+ ovPort.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ ovPort.nVersion.nVersion = OMX_VERSION;
+ ovPort.nPortIndex = 130;
+ ovPort.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ ErrorCode = OMX_SetParameter(component, OMX_IndexParamVideoPortFormat, &ovPort);
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Failed to set AVC coding type.\n");
+ }
+
+ memset(&ivPort, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+ ivPort.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ ivPort.nVersion.nVersion = OMX_VERSION;
+ ivPort.nPortIndex = 131;
+ ivPort.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ ivPort.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ ErrorCode = OMX_SetParameter(component, OMX_IndexParamVideoPortFormat, &ivPort);
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Failed to set color format.\n");
+ }
+
+ output_port_def.nBufferCountActual = 16;
+ ErrorCode = OMX_SetParameter(component, OMX_IndexParamPortDefinition, &output_port_def);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ }
+
+ return ErrorCode;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::prepare_input_buffers(unsigned int num)
+{
+ ErrorCode = OMX_ErrorNone;
+ unsigned int * pPrivateData;
+
+ for (unsigned int i = 0; i < num; i++)
+ {
+ pPrivateData = &input_buffer_number[i];
+ *pPrivateData = (1 << i);
+ input_buffer_usage |= *pPrivateData;
+ ErrorCode = OMX_AllocateBuffer(component, &input_buffer_header[i], 130, pPrivateData, input_port_def.nBufferSize);
+
+ if (ErrorCode == OMX_ErrorNone) {
+ fprintf(stderr, "Okay:prepare_input_buffers:Output buffer %u allocated,%d.\n", i + 1, input_port_def.nBufferSize);
+ }
+ else {
+ fprintf(stderr, "Err:prepare_input_buffers:%d. %s\n", i, OMX_strerror(ErrorCode));
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::prepare_output_buffers(unsigned int num)
+{
+ ErrorCode = OMX_ErrorNone;
+ unsigned int *pPrivateData;
+
+ for (unsigned int i = 0; i < num; i++) {
+ pPrivateData = &output_buffer_number[i];
+ *pPrivateData = (1 << i);
+ output_buffer_usage |= *pPrivateData;
+ ErrorCode = OMX_AllocateBuffer(component, &output_buffer_header[i], output_port_def.nPortIndex, pPrivateData, output_port_def.nBufferSize);
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Failed to alloc output buffer %u. %s\n", i, OMX_strerror(ErrorCode));
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_BUFFERHEADERTYPE * hello_video2::get_free_input_buffer()
+{
+ while (true) {
+ for (unsigned int i = 0; i < input_port_def.nBufferCountActual; i++) {
+ if ((input_buffer_usage & *((unsigned int *)input_buffer_header[i]->pAppPrivate)) != 0) {
+ return input_buffer_header[i];
+ }
+ }
+ OMXWaitForEmpty();
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+OMX_BUFFERHEADERTYPE * hello_video2::get_free_output_buffer()
+{
+ while (true) {
+ for (unsigned int i = 0; i < output_port_def.nBufferCountActual; i++) {
+ if ((output_buffer_usage & *((unsigned int *)output_buffer_header[i]->pAppPrivate)) != 0) {
+ return output_buffer_header[i];
+ }
+ }
+ OMXWaitForFilled();
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+int main (int argc, char **argv)
+{
+ int size;
+ FILE * in = NULL;
+ unsigned char buff[500000];
+ hello_video2 client;
+
+ mutex_init();
+
+ if (pthread_create(&thread_t1, NULL, __port_settings_changed_thread, (void *)&client) < 0) {
+ fprintf(stderr, "thread1 create error:");
+ exit(0);
+ }
+
+ in = fopen(argv[1], "r");
+ if (in == NULL) {
+ printf("No such file.\n");
+ exit(0);
+ }
+
+ size = fread(buff, 1, 500000, in);
+ fclose(in);
+
+ client.decode_frame(buff, size);
+////////////////////////////////////////////////////////////////////
+// //
+// I dont worry form now. //
+// //
+////////////////////////////////////////////////////////////////////
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "bcm_host.h"
+#include "IL/OMX_Component.h"
+#include "IL/OMX_Types.h"
+#include "IL/OMX_Index.h"
+#include "IL/OMX_Broadcom.h"
+#include "IL/OMX_IVCommon.h"
+
+struct NALu
+{
+ unsigned int pos, size, type;
+ NALu(unsigned int p, unsigned int s, unsigned int t)
+ : pos(p), size(s), type(t)
+ { };
+
+ NALu() { };
+
+ ~NALu() { };
+};
+
+typedef struct
+{
+ char file_path[128];
+ unsigned int size;
+ void** data;
+} DUMP_FILE_INFO;
+
+pthread_mutex_t OMXMutex, OMXEmptyMutex, OMXFilledMutex, OMXPortSettingsChangedMutex;
+pthread_cond_t OMXStateCond, OMXEmptyCond, OMXFilledCond, OMXPortSettingsChangedCond;
+
+void mutex_init()
+{
+ if (pthread_mutex_init(&OMXMutex, NULL) != 0) {
+ printf("Can't init state mutex.\n");
+ }
+
+ if (pthread_mutex_init(&OMXEmptyMutex, NULL) != 0) {
+ printf("Can't init empty mutex.\n");
+ }
+
+ if (pthread_mutex_init(&OMXFilledMutex, NULL) != 0) {
+ printf("Can't init filled mutex.\n");
+ };
+
+ if (pthread_mutex_init(&OMXPortSettingsChangedMutex, NULL) != 0) {
+ printf("Can't init port settings changed mutex.\n");
+ }
+
+ OMXStateCond = PTHREAD_COND_INITIALIZER;
+ OMXEmptyCond = PTHREAD_COND_INITIALIZER;
+ OMXFilledCond = PTHREAD_COND_INITIALIZER;
+ OMXPortSettingsChangedCond = PTHREAD_COND_INITIALIZER;
+};
+
+/*****************************************************************************/
+
+struct hello_video2
+{
+public:
+ hello_video2();
+ ~hello_video2();
+
+ OMX_ERRORTYPE decode_frame(unsigned char * data, unsigned int size);
+ OMX_BUFFERHEADERTYPE * get_free_input_buffer();
+ OMX_BUFFERHEADERTYPE * get_free_output_buffer();
+ OMX_ERRORTYPE get_port_parameters();
+ OMX_ERRORTYPE set_state(OMX_STATETYPE nState);
+ OMX_ERRORTYPE set_port_parameters();
+ OMX_ERRORTYPE prepare_input_buffers(unsigned int num);
+ OMX_ERRORTYPE prepare_output_buffers(unsigned int num);
+ OMX_STATETYPE get_state();
+ OMX_ERRORTYPE block_until_port_changed(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL bEnabled);
+ OMX_ERRORTYPE port_settings_changed();
+ OMX_ERRORTYPE fill_buffer(OMX_PTR pAppD, OMX_BUFFERHEADERTYPE *buffer);
+ OMX_ERRORTYPE fill_buffer();
+ OMX_ERRORTYPE _write_yuv_dump_to_file(const char *file_path, void *data, int size);
+ OMX_ERRORTYPE write_yuv_dump_to_file(const char *file_path, void *data, int size);
+ const char* dump_compression_video_format(OMX_VIDEO_CODINGTYPE c);
+ const char* dump_compression_image_format(OMX_IMAGE_CODINGTYPE c);
+ const char* dump_color_format(OMX_COLOR_FORMATTYPE c);
+ void dump_portdef(OMX_PARAM_PORTDEFINITIONTYPE* portdef);
+ void dump_port(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL dumpformats);
+
+ static OMX_ERRORTYPE Init();
+ static OMX_ERRORTYPE DeInit();
+ static const char * OMX_strerror(OMX_ERRORTYPE errorCode);
+ static unsigned int FindAllNALu(unsigned char * source, unsigned int size, NALu * table);
+
+ friend OMX_ERRORTYPE eventHandler(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2, OMX_PTR eventData);
+ friend OMX_ERRORTYPE bufferEmptied(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_BUFFERHEADERTYPE * buffer);
+ friend OMX_ERRORTYPE bufferFilled(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_BUFFERHEADERTYPE * buffer);
+public:
+ OMX_CALLBACKTYPE callback;
+ OMX_ERRORTYPE ErrorCode;
+ unsigned int input_buffer_usage;
+ unsigned int output_buffer_usage;
+ OMX_STATETYPE component_state;
+ OMX_HANDLETYPE component;
+ unsigned int input_buffer_number[20];
+ unsigned int output_buffer_number[20];
+ OMX_PARAM_PORTDEFINITIONTYPE input_port_def;
+ OMX_PARAM_PORTDEFINITIONTYPE output_port_def;
+ OMX_BUFFERHEADERTYPE* input_buffer_header[20];
+ OMX_BUFFERHEADERTYPE* output_buffer_header[100];
+};
+
+/*****************************************************************************/
+
+hello_video2 * phello_video2 = NULL;
+/**/
+void OMXWaitForState(OMX_STATETYPE nState)
+{
+ pthread_mutex_lock(&OMXMutex);
+ while (phello_video2->component_state != nState) {
+ pthread_cond_wait(&OMXStateCond, &OMXMutex);
+ }
+ pthread_mutex_unlock(&OMXMutex);
+}
+void OMXWaitForEmpty()
+{
+ pthread_mutex_lock(&OMXEmptyMutex);
+ pthread_cond_wait(&OMXEmptyCond, &OMXEmptyMutex);
+ pthread_mutex_unlock(&OMXEmptyMutex);
+}
+void OMXWaitForFilled()
+{
+ pthread_mutex_lock(&OMXFilledMutex);
+ pthread_cond_wait(&OMXFilledCond, &OMXFilledMutex);
+ pthread_mutex_unlock(&OMXFilledMutex);
+}
+void OMXWakeUp(OMX_STATETYPE nState)
+{
+ pthread_mutex_lock(&OMXMutex);
+ phello_video2->component_state = nState;
+ pthread_cond_signal(&OMXStateCond);
+ pthread_mutex_unlock(&OMXMutex);
+}
+void OMXWakeUpEmpty()
+{
+ pthread_mutex_lock(&OMXEmptyMutex);
+ pthread_cond_signal(&OMXEmptyCond);
+ pthread_mutex_unlock(&OMXEmptyMutex);
+}
+void OMXWakeUpFilled()
+{
+ pthread_mutex_lock(&OMXFilledMutex);
+ pthread_cond_signal(&OMXFilledCond);
+ pthread_mutex_unlock(&OMXFilledMutex);
+}
+
+void OMWaitForXPortSettingsChanged()
+{
+ pthread_mutex_lock(&OMXPortSettingsChangedMutex);
+ pthread_cond_wait(&OMXPortSettingsChangedCond, &OMXPortSettingsChangedMutex);
+ pthread_mutex_unlock(&OMXPortSettingsChangedMutex);
+}
+
+void OMXWakeupPortSettingsChanged()
+{
+ pthread_mutex_lock(&OMXPortSettingsChangedMutex);
+ pthread_cond_signal(&OMXPortSettingsChangedCond);
+ pthread_mutex_unlock(&OMXPortSettingsChangedMutex);
+}
--- /dev/null
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "hello_video2_tizen.h"
+
+#define OMX_INIT_STRUCTURE(a) \
+ memset(&(a), 0, sizeof(a)); \
+ (a).nSize = sizeof(a); \
+ (a).nVersion.nVersion = OMX_VERSION; \
+ (a).nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
+ (a).nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
+ (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \
+ (a).nVersion.s.nStep = OMX_VERSION_STEP
+
+static pthread_t thread_t1;
+
+static void *__port_settings_changed_thread(void *data)
+{
+ hello_video2 *hello_video = (hello_video2*)data;
+
+ while (1) {
+ OMWaitForXPortSettingsChanged();
+
+ hello_video->port_settings_changed();
+ hello_video->fill_buffer();
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::Init()
+{
+ OMX_ERRORTYPE ErrorCode = OMX_Init();
+
+ if (ErrorCode == OMX_ErrorNone) {
+ return ErrorCode;
+ }
+ else {
+ printf("Err:%s\n", OMX_strerror(ErrorCode));
+
+ return ErrorCode;
+ }
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::DeInit()
+{
+ OMX_ERRORTYPE ErrorCode = OMX_Deinit();
+
+ if (ErrorCode == OMX_ErrorNone) {
+ return ErrorCode;
+ }
+ else {
+ printf("Err:%s\n", OMX_strerror(ErrorCode));
+
+ return ErrorCode;
+ }
+};
+
+/******************************************************************************/
+
+const char * hello_video2::OMX_strerror(OMX_ERRORTYPE ErrorCode)
+{
+ switch (ErrorCode)
+ {
+ case OMX_ErrorNone:
+ return "Operation completed succesfully.";
+ case OMX_ErrorInsufficientResources:
+ return "There were insufficient resources to perform the requested operation.";
+ case OMX_ErrorUndefined:
+ return "There was an error, but the caues of the error could not be determined.";
+ case OMX_ErrorInvalidComponentName:
+ return "The component name string was not valid.";
+ case OMX_ErrorComponentNotFound:
+ return "No component with the specified name string was found";
+ case OMX_ErrorInvalidComponent:
+ return "The component specified did not have a \"OMX_ComponentInit\" or \"OMX_ComponentDeInit\" entry point.";
+ case OMX_ErrorBadParameter:
+ return "One or more parameters were invalid.";
+ case OMX_ErrorNotImplemented:
+ return "The requested function is not implemented.";
+ case OMX_ErrorUnderflow:
+ return "The buffer was emptied before the next buffer was ready.";
+ case OMX_ErrorOverflow:
+ return "The buffer was not available whe it was needed.";
+ case OMX_ErrorHardware:
+ return "The hardware failed to respond as expected.";
+ case OMX_ErrorInvalidState:
+ return "The component is in the state OMX_StateInvalid.";
+ case OMX_ErrorStreamCorrupt:
+ return "Stream is found to be corrupt.";
+ case OMX_ErrorPortsNotCompatible:
+ return "Ports being connected are not compatible.";
+ case OMX_ErrorResourcesLost:
+ return "Resources allocated to an idle component have been lost resulting in the component returning to the loaded state.";
+ case OMX_ErrorNoMore:
+ return "No more indices can be enumerated.";
+ case OMX_ErrorVersionMismatch:
+ return "The component detected a version mismatch.";
+ case OMX_ErrorNotReady:
+ return "The component is not ready to return data at this time.";
+ case OMX_ErrorTimeout:
+ return "There was a timeout that occured.";
+ case OMX_ErrorSameState:
+ return "The component cannot complete the transition to state it is already in.";
+ case OMX_ErrorResourcesPreempted:
+ return "Resources allocated to an executing or paused component have been preempted. Returning to Idle state.";
+ case OMX_ErrorPortUnresponsiveDuringAllocation:
+ return "During a call to UseBuffer() port became unresponsive.";
+ case OMX_ErrorPortUnresponsiveDuringDeallocation:
+ return "During a call to FreeBuffer() port became unresponsive.";
+ case OMX_ErrorPortUnresponsiveDuringStop:
+ return "During stopping of a port, it became unresponsive.";
+ case OMX_ErrorIncorrectStateTransition:
+ return "Attempting a state transition that is not allowed.";
+ case OMX_ErrorIncorrectStateOperation:
+ return "Attempting a state transition that is not allowed.";
+ case OMX_ErrorUnsupportedSetting:
+ return "The values encapsulated in the parameter or config structure are not supported.";
+ case OMX_ErrorUnsupportedIndex:
+ return "The parameter or config indicated by the given index is not supported.";
+ case OMX_ErrorBadPortIndex:
+ return "The port index supplied is incorrect.";
+ case OMX_ErrorPortUnpopulated:
+ return "The port has lost one or more of its buffers an it thus unpopulated.";
+ case OMX_ErrorDynamicResourcesUnavailable:
+ return "Component suspended due to inability to acquire dynamic resources.";
+ case OMX_ErrorMbErrorsInFrame:
+ return "Corrupted frame.";
+ case OMX_ErrorFormatNotDetected:
+ return "OMX_ErrorFormatNotDetected";
+ case OMX_ErrorSeperateTablesUsed:
+ return "Separate table information is being used.";
+ default:
+ return "Error not defined. Error is: ";
+ }
+}
+
+/******************************************************************************/
+
+unsigned int hello_video2::FindAllNALu(unsigned char *source, unsigned int size, NALu *table)
+{
+ unsigned int num = 0;
+ for (unsigned int i = 0; i < size; i++)
+ {
+#if 0
+ if (source[i] == 0x00)
+ if (source[i + 1] == 0x00)
+ if (source[i + 2] == 0x00)
+#else
+ if ((source[i] + source[i + 1] + source[i + 2]) == 0x00)
+#endif
+ if (source[i + 3] == 0x01)
+ {
+// fprintf(stderr, "%s[%d]i(%d)\n", __func__, __LINE__, i);
+ table[num] = NALu(i, size - i, ((unsigned int)(source[i + 4] & 31)));
+
+ if (num != 0)
+ {
+ table[num - 1].size = i - table[num - 1].pos;
+ };
+
+ num++;
+ };
+ };
+
+ return num;
+};
+
+
+/******************************************************************************/
+
+OMX_ERRORTYPE eventHandler(OMX_HANDLETYPE hComp, OMX_PTR pAppD,
+ OMX_EVENTTYPE event, OMX_U32 data1,
+ OMX_U32 data2, OMX_PTR eventData)
+{
+ switch(event) {
+ case OMX_EventCmdComplete:
+ switch (data1) {
+ case OMX_CommandStateSet:
+ OMXWakeUp((OMX_STATETYPE) data2);
+ break;
+ case OMX_CommandFlush:
+ break;
+ case OMX_CommandPortDisable:
+ if (data2 == 130) phello_video2->input_port_def.bEnabled = OMX_FALSE;
+ if (data2 == 131) phello_video2->output_port_def.bEnabled = OMX_FALSE;
+ break;
+ case OMX_CommandPortEnable:
+ if (data2 == 130) phello_video2->input_port_def.bEnabled = OMX_TRUE;
+ if (data2 == 131) phello_video2->output_port_def.bEnabled = OMX_TRUE;
+ break;
+ case OMX_CommandMarkBuffer:
+ break;
+ default:
+ break;
+ }
+ break;
+ case OMX_EventError:
+ fprintf(stderr, "Err:%s[%d]%s\n.", __func__, __LINE__, hello_video2::OMX_strerror((OMX_ERRORTYPE) data1));
+ break;
+ case OMX_EventPortSettingsChanged:
+ fprintf(stderr, "Port settings changed...\n");
+ OMXWakeupPortSettingsChanged();
+ break;
+ case OMX_EventBufferFlag:
+ case OMX_EventResourcesAcquired:
+ case OMX_EventDynamicResourcesAvailable:
+ case OMX_EventMark:
+ break;
+ default:
+ break;
+ }
+
+ return OMX_ErrorNone;
+};
+
+/******************************************************************************/
+
+OMX_ERRORTYPE bufferEmptied(OMX_HANDLETYPE hComp, OMX_PTR pAppD,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ phello_video2->input_buffer_usage |= *((unsigned int *)buffer->pAppPrivate);
+
+ OMXWakeUpEmpty();
+ return OMX_ErrorNone;
+};
+
+/******************************************************************************/
+
+OMX_ERRORTYPE bufferFilled(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_BUFFERHEADERTYPE *buffer)
+{
+ phello_video2->output_buffer_usage |= *((unsigned int *)buffer->pAppPrivate);
+
+ OMXWakeUpFilled();
+
+ if (buffer->nFilledLen == 0) {
+ phello_video2->fill_buffer();
+
+ return OMX_ErrorNone;
+ }
+
+ phello_video2->fill_buffer(pAppD, buffer);
+
+ return OMX_ErrorNone;
+};
+
+/******************************************************************************/
+int tbm_drm;
+hello_video2::hello_video2()
+{
+ bcm_host_init();
+
+ _tbm_bufmgr = tbm_bufmgr_init(tbm_drm);
+ if(_tbm_bufmgr == NULL){
+ fprintf(stderr, "TBM initialization failed\n");
+ exit(0);
+ }
+
+ hello_video2::Init();
+
+ input_buffer_usage = 0;
+ output_buffer_usage = 0;
+ input_buffer_number[0] = 0;
+ output_buffer_number[0] = 0;
+ phello_video2 = this;
+
+ callback.EventHandler = &eventHandler;
+ callback.EmptyBufferDone = &bufferEmptied;
+ callback.FillBufferDone = &bufferFilled;
+
+ memset(&input_port_def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ input_port_def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+ input_port_def.nVersion.nVersion = OMX_VERSION;
+ input_port_def.nPortIndex = 130;
+
+ memset(&output_port_def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ output_port_def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+ output_port_def.nVersion.nVersion = OMX_VERSION;
+ output_port_def.nPortIndex = 131;
+
+ OMX_ERRORTYPE ErrorCode = OMX_GetHandle(&component, (OMX_STRING)"OMX.broadcom.video_decode", NULL, &callback);
+
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ OMX_FreeHandle(component);
+ component = NULL;
+
+ return;
+ }
+
+ get_port_parameters();
+
+ set_port_parameters();
+
+ ErrorCode = OMX_SendCommand(component, OMX_CommandPortDisable, OMX_ALL, NULL);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ }
+
+ ErrorCode = OMX_SendCommand(component, OMX_CommandStateSet, OMX_StateIdle ,NULL);
+
+ if (ErrorCode != OMX_ErrorNone)
+ {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ return;
+ }
+
+ OMXWaitForState(OMX_StateIdle);
+}
+
+/******************************************************************************/
+
+hello_video2::~hello_video2()
+{
+}
+
+/******************************************************************************/
+
+const char* hello_video2::dump_compression_video_format(OMX_VIDEO_CODINGTYPE c) {
+ static char *f = NULL;
+ switch(c) {
+ case OMX_VIDEO_CodingUnused: return "not used";
+ case OMX_VIDEO_CodingAutoDetect: return "autodetect";
+ case OMX_VIDEO_CodingMPEG2: return "MPEG2";
+ case OMX_VIDEO_CodingH263: return "H.263";
+ case OMX_VIDEO_CodingMPEG4: return "MPEG4";
+ case OMX_VIDEO_CodingWMV: return "Windows Media Video";
+ case OMX_VIDEO_CodingRV: return "RealVideo";
+ case OMX_VIDEO_CodingAVC: return "H.264/AVC";
+ case OMX_VIDEO_CodingMJPEG: return "Motion JPEG";
+ case OMX_VIDEO_CodingVP6: return "VP6";
+ case OMX_VIDEO_CodingVP7: return "VP7";
+ case OMX_VIDEO_CodingVP8: return "VP8";
+ case OMX_VIDEO_CodingYUV: return "Raw YUV video";
+ case OMX_VIDEO_CodingSorenson: return "Sorenson";
+ case OMX_VIDEO_CodingTheora: return "OGG Theora";
+ case OMX_VIDEO_CodingMVC: return "H.264/MVC";
+
+ default:
+ if (f == NULL) {
+ f = (char*)calloc(64, sizeof(char));
+ if(f == NULL) {
+ fprintf(stderr, "Failed to allocate memory");
+ exit(-1);
+ }
+ }
+ snprintf(f, 64 * sizeof(char) - 1, "format type 0x%08x", c);
+ return f;
+ }
+}
+
+/******************************************************************************/
+
+const char* hello_video2::dump_compression_image_format(OMX_IMAGE_CODINGTYPE c) {
+ static char *f = NULL;
+ switch(c) {
+ case OMX_IMAGE_CodingUnused: return "Value when format is N/A";
+ case OMX_IMAGE_CodingAutoDetect: return "Auto detection of image format";
+ case OMX_IMAGE_CodingJPEG: return "JPEG/JFIF image format";
+ case OMX_IMAGE_CodingJPEG2K: return "JPEG 2000 image format";
+ case OMX_IMAGE_CodingEXIF: return "EXIF image format";
+ case OMX_IMAGE_CodingTIFF: return "TIFF image format";
+ case OMX_IMAGE_CodingGIF: return "Graphics image format";
+ case OMX_IMAGE_CodingPNG: return "PNG image format";
+ case OMX_IMAGE_CodingLZW: return "LZW image format";
+ case OMX_IMAGE_CodingBMP: return "Windows Bitmap format";
+ case OMX_IMAGE_CodingKhronosExtensions: return "Reserved region for introducing Khronos Standard Extensions";
+ case OMX_IMAGE_CodingVendorStartUnused: return "Reserved region for introducing Vendor Extensions";
+ case OMX_IMAGE_CodingTGA: return "TGA format";
+ case OMX_IMAGE_CodingPPM: return "PPM format";
+ default:
+ if (f == NULL) {
+ f = (char*)calloc(64, sizeof(char));
+ if(f == NULL) {
+ fprintf(stderr, "Failed to allocate memory");
+ exit(-1);
+ }
+ }
+ snprintf(f, 64 * sizeof(char) - 1, "format type 0x%08x", c);
+ return f;
+ }
+}
+
+/******************************************************************************/
+
+const char* hello_video2::dump_color_format(OMX_COLOR_FORMATTYPE c) {
+ static char *f = NULL;
+ switch(c) {
+ case OMX_COLOR_FormatUnused: return "OMX_COLOR_FormatUnused: not used";
+ case OMX_COLOR_FormatMonochrome: return "OMX_COLOR_FormatMonochrome";
+ case OMX_COLOR_Format8bitRGB332: return "OMX_COLOR_Format8bitRGB332";
+ case OMX_COLOR_Format12bitRGB444: return "OMX_COLOR_Format12bitRGB444";
+ case OMX_COLOR_Format16bitARGB4444: return "OMX_COLOR_Format16bitARGB4444";
+ case OMX_COLOR_Format16bitARGB1555: return "OMX_COLOR_Format16bitARGB1555";
+ case OMX_COLOR_Format16bitRGB565: return "OMX_COLOR_Format16bitRGB565";
+ case OMX_COLOR_Format16bitBGR565: return "OMX_COLOR_Format16bitBGR565";
+ case OMX_COLOR_Format18bitRGB666: return "OMX_COLOR_Format18bitRGB666";
+ case OMX_COLOR_Format18bitARGB1665: return "OMX_COLOR_Format18bitARGB1665";
+ case OMX_COLOR_Format19bitARGB1666: return "OMX_COLOR_Format19bitARGB1666";
+ case OMX_COLOR_Format24bitRGB888: return "OMX_COLOR_Format24bitRGB888";
+ case OMX_COLOR_Format24bitBGR888: return "OMX_COLOR_Format24bitBGR888";
+ case OMX_COLOR_Format24bitARGB1887: return "OMX_COLOR_Format24bitARGB1887";
+ case OMX_COLOR_Format25bitARGB1888: return "OMX_COLOR_Format25bitARGB1888";
+ case OMX_COLOR_Format32bitBGRA8888: return "OMX_COLOR_Format32bitBGRA8888";
+ case OMX_COLOR_Format32bitARGB8888: return "OMX_COLOR_Format32bitARGB8888";
+ case OMX_COLOR_FormatYUV411Planar: return "OMX_COLOR_FormatYUV411Planar";
+ case OMX_COLOR_FormatYUV411PackedPlanar: return "OMX_COLOR_FormatYUV411PackedPlanar: Planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_FormatYUV420Planar: return "OMX_COLOR_FormatYUV420Planar: Planar YUV, 4:2:0 (I420)";
+ case OMX_COLOR_FormatYUV420PackedPlanar: return "OMX_COLOR_FormatYUV420PackedPlanar: Planar YUV, 4:2:0 (I420), planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_FormatYUV420SemiPlanar: return "OMX_COLOR_FormatYUV420SemiPlanar, Planar YUV, 4:2:0 (NV12), U and V planes interleaved with first U value";
+ case OMX_COLOR_FormatYUV422Planar: return "OMX_COLOR_FormatYUV422Planar";
+ case OMX_COLOR_FormatYUV422PackedPlanar: return "OMX_COLOR_FormatYUV422PackedPlanar: Planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_FormatYUV422SemiPlanar: return "OMX_COLOR_FormatYUV422SemiPlanar";
+ case OMX_COLOR_FormatYCbYCr: return "OMX_COLOR_FormatYCbYCr";
+ case OMX_COLOR_FormatYCrYCb: return "OMX_COLOR_FormatYCrYCb";
+ case OMX_COLOR_FormatCbYCrY: return "OMX_COLOR_FormatCbYCrY";
+ case OMX_COLOR_FormatCrYCbY: return "OMX_COLOR_FormatCrYCbY";
+ case OMX_COLOR_FormatYUV444Interleaved: return "OMX_COLOR_FormatYUV444Interleaved";
+ case OMX_COLOR_FormatRawBayer8bit: return "OMX_COLOR_FormatRawBayer8bit";
+ case OMX_COLOR_FormatRawBayer10bit: return "OMX_COLOR_FormatRawBayer10bit";
+ case OMX_COLOR_FormatRawBayer8bitcompressed: return "OMX_COLOR_FormatRawBayer8bitcompressed";
+ case OMX_COLOR_FormatL2: return "OMX_COLOR_FormatL2";
+ case OMX_COLOR_FormatL4: return "OMX_COLOR_FormatL4";
+ case OMX_COLOR_FormatL8: return "OMX_COLOR_FormatL8";
+ case OMX_COLOR_FormatL16: return "OMX_COLOR_FormatL16";
+ case OMX_COLOR_FormatL24: return "OMX_COLOR_FormatL24";
+ case OMX_COLOR_FormatL32: return "OMX_COLOR_FormatL32";
+ case OMX_COLOR_FormatYUV420PackedSemiPlanar: return "OMX_COLOR_FormatYUV420PackedSemiPlanar: Planar YUV, 4:2:0 (NV12), planes fragmented when a frame is split in multiple buffers, U and V planes interleaved with first U value";
+ case OMX_COLOR_FormatYUV422PackedSemiPlanar: return "OMX_COLOR_FormatYUV422PackedSemiPlanar: Planes fragmented when a frame is split in multiple buffers";
+ case OMX_COLOR_Format18BitBGR666: return "OMX_COLOR_Format18BitBGR666";
+ case OMX_COLOR_Format24BitARGB6666: return "OMX_COLOR_Format24BitARGB6666";
+ case OMX_COLOR_Format24BitABGR6666: return "OMX_COLOR_Format24BitABGR6666";
+ case OMX_COLOR_Format32bitABGR8888: return "OMX_COLOR_Format32bitABGR8888";
+ case OMX_COLOR_Format8bitPalette: return "OMX_COLOR_Format8bitPalette";
+ case OMX_COLOR_FormatYUVUV128: return "OMX_COLOR_FormatYUVUV128";
+ case OMX_COLOR_FormatRawBayer12bit: return "OMX_COLOR_FormatRawBayer12bit";
+ case OMX_COLOR_FormatBRCMEGL: return "OMX_COLOR_FormatBRCMEGL";
+ case OMX_COLOR_FormatBRCMOpaque: return "OMX_COLOR_FormatBRCMOpaque";
+ case OMX_COLOR_FormatYVU420PackedPlanar: return "OMX_COLOR_FormatYVU420PackedPlanar";
+ case OMX_COLOR_FormatYVU420PackedSemiPlanar: return "OMX_COLOR_FormatYVU420PackedSemiPlanar";
+ default:
+ if (f == NULL) {
+ f = (char*)calloc(64, sizeof(char));
+ if(f == NULL) {
+ fprintf(stderr, "Failed to allocate memory");
+ exit(-1);
+ }
+ }
+ snprintf(f, 64 * sizeof(char) - 1, "format type 0x%08x", c);
+ return f;
+ }
+}
+
+/******************************************************************************/
+void hello_video2::dump_portdef(OMX_PARAM_PORTDEFINITIONTYPE* portdef) {
+ fprintf(stderr, "Port %d is %s, %s, buffers wants:%d needs:%d, size:%d, pop:%d, aligned:%d",
+ portdef->nPortIndex,
+ (portdef->eDir == OMX_DirInput ? "input" : "output"),
+ (portdef->bEnabled == OMX_TRUE ? "enabled" : "disabled"),
+ portdef->nBufferCountActual,
+ portdef->nBufferCountMin,
+ portdef->nBufferSize,
+ portdef->bPopulated,
+ portdef->nBufferAlignment);
+
+ OMX_VIDEO_PORTDEFINITIONTYPE *viddef = &portdef->format.video;
+ OMX_IMAGE_PORTDEFINITIONTYPE *imgdef = &portdef->format.image;
+ switch(portdef->eDomain) {
+ case OMX_PortDomainVideo:
+ fprintf(stderr, "Video type:\n"
+ "\tWidth:\t\t%d\n"
+ "\tHeight:\t\t%d\n"
+ "\tStride:\t\t%d\n"
+ "\tSliceHeight:\t%d\n"
+ "\tBitrate:\t%d\n"
+ "\tFramerate:\t%.02f\n"
+ "\tError hiding:\t%s\n"
+ "\tCodec:\t\t%s\n"
+ "\tColor:\t\t%s\n",
+ viddef->nFrameWidth,
+ viddef->nFrameHeight,
+ viddef->nStride,
+ viddef->nSliceHeight,
+ viddef->nBitrate,
+ ((float)viddef->xFramerate / (float)65536),
+ (viddef->bFlagErrorConcealment == OMX_TRUE ? "yes" : "no"),
+ dump_compression_video_format(viddef->eCompressionFormat),
+ dump_color_format(viddef->eColorFormat));
+ break;
+ case OMX_PortDomainImage:
+ fprintf(stderr, "Image type:\n"
+ "\tWidth:\t\t%d\n"
+ "\tHeight:\t\t%d\n"
+ "\tStride:\t\t%d\n"
+ "\tSliceHeight:\t%d\n"
+ "\tError hiding:\t%s\n"
+ "\tCodec:\t\t%s\n"
+ "\tColor:\t\t%s\n",
+ imgdef->nFrameWidth,
+ imgdef->nFrameHeight,
+ imgdef->nStride,
+ imgdef->nSliceHeight,
+ (imgdef->bFlagErrorConcealment == OMX_TRUE ? "yes" : "no"),
+ dump_compression_image_format(imgdef->eCompressionFormat),
+ dump_color_format(imgdef->eColorFormat));
+ break;
+ default:
+ break;
+ }
+}
+
+/******************************************************************************/
+
+void hello_video2::dump_port(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL dumpformats) {
+ OMX_ERRORTYPE r;
+ OMX_PARAM_PORTDEFINITIONTYPE portdef;
+
+ OMX_INIT_STRUCTURE(portdef);
+ portdef.nPortIndex = nPortIndex;
+ if((r = OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &portdef)) != OMX_ErrorNone) {
+ fprintf(stderr, "Failed to get port definition for port %d:%s\n", nPortIndex, OMX_strerror(r));
+ }
+ dump_portdef(&portdef);
+ if(dumpformats) {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE portformat;
+ OMX_INIT_STRUCTURE(portformat);
+ portformat.nPortIndex = nPortIndex;
+ portformat.nIndex = 0;
+ r = OMX_ErrorNone;
+ fprintf(stderr, "Port %d supports these video formats:", nPortIndex);
+ while(r == OMX_ErrorNone) {
+ if((r = OMX_GetParameter(hComponent, OMX_IndexParamVideoPortFormat, &portformat)) == OMX_ErrorNone) {
+ fprintf(stderr, "\t%s, compression: %s", dump_color_format(portformat.eColorFormat), dump_compression_video_format(portformat.eCompressionFormat));
+ portformat.nIndex++;
+ }
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+/******************************************************************************/
+OMX_STATETYPE hello_video2::get_state()
+{
+ ErrorCode = OMX_GetState(component, &component_state);
+
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Error while obtaining component state. %s\n", OMX_strerror(ErrorCode));
+ }
+
+ return component_state;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::set_state(OMX_STATETYPE nState)
+{
+ OMX_SendCommand(component, OMX_CommandStateSet, nState, NULL);
+ OMXWaitForState(nState);
+ return OMX_ErrorNone;
+};
+
+OMX_ERRORTYPE hello_video2::block_until_port_changed(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL bEnabled) {
+ OMX_ERRORTYPE r;
+ OMX_PARAM_PORTDEFINITIONTYPE portdef;
+ OMX_U32 i = 0;
+
+ OMX_INIT_STRUCTURE(portdef);
+ portdef.nPortIndex = nPortIndex;
+
+ while(i++ == 0 || portdef.bEnabled != bEnabled) {
+ if((r = OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &portdef)) != OMX_ErrorNone) {
+ fprintf(stderr, "Failed to get port definition:%s\n", OMX_strerror(r));
+ }
+ if(portdef.bEnabled != bEnabled) {
+ usleep(10000);
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::decode_frame(unsigned char * data, unsigned int size)
+{
+ OMX_ERRORTYPE ErrorCode = OMX_ErrorNone;
+
+ if (input_port_def.bEnabled == OMX_FALSE) {
+ fprintf(stderr, "Check:%s[%d] input_port_def.bEnabled is OMX_FALSE\n", __func__, __LINE__);
+ ErrorCode = OMX_SendCommand(component, OMX_CommandPortEnable, 130, NULL);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "Err:%s\n", OMX_strerror(ErrorCode));
+ return OMX_ErrorNone;
+ }
+ block_until_port_changed(component, input_port_def.nPortIndex, OMX_TRUE);
+ }
+
+ if (input_buffer_number[0] == 0)
+ {
+ ErrorCode = prepare_input_buffers(20);
+ if (ErrorCode != OMX_ErrorNone) {
+ return OMX_ErrorNone;
+ }
+ }
+
+ if (get_state() != OMX_StateExecuting) {
+ ErrorCode = set_state(OMX_StateExecuting);
+ }
+
+ if (size <= input_port_def.nBufferSize) {
+ OMX_BUFFERHEADERTYPE * iBuffer = get_free_input_buffer();
+ memcpy(iBuffer->pBuffer, data, size);
+ iBuffer->nOffset = 0;
+ iBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+ iBuffer->nFilledLen = size;
+ input_buffer_usage ^= *((unsigned int *)iBuffer->pAppPrivate);
+ OMX_EmptyThisBuffer(component, iBuffer);
+ }
+ else {
+ NALu nalu[1000];
+ unsigned int nSize = FindAllNALu(data, size, nalu);
+ for (unsigned int i = 0; i < nSize; i ++)
+ {
+ OMX_BUFFERHEADERTYPE * iBuffer = get_free_input_buffer();
+ void * pStart = &data[nalu[i].pos];
+ memcpy(iBuffer->pBuffer, pStart, nalu[i].size);
+ iBuffer->nOffset = 0;
+ iBuffer->nFlags = OMX_BUFFERFLAG_EOS;
+ iBuffer->nFilledLen = nalu[i].size;
+ input_buffer_usage ^= *((unsigned int *)iBuffer->pAppPrivate);
+ OMX_EmptyThisBuffer(component, iBuffer);
+ fprintf(stderr, "OMX_EmptyThisBuffer:%d/%d\n", i+1, nSize);
+ usleep(50000);
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+void *write_yuv_dump_to_file_thread(void *data) {
+ DUMP_FILE_INFO *dump_file_info;
+
+ dump_file_info = (DUMP_FILE_INFO*)data;
+
+ phello_video2->_write_yuv_dump_to_file(dump_file_info->file_path, *dump_file_info->data, dump_file_info->size);
+
+ free(*dump_file_info->data);
+ free(data);
+
+ return NULL;
+}
+
+OMX_ERRORTYPE hello_video2::write_yuv_dump_to_file(const char *file_path, void *data, int size)
+{
+ pthread_t thread_t;
+ char *mdata;
+ DUMP_FILE_INFO *box_info;
+
+ box_info = (DUMP_FILE_INFO*)malloc(sizeof(DUMP_FILE_INFO));
+
+ mdata = (char*)malloc(size);
+ if (!mdata) {
+ return OMX_ErrorNone;
+ }
+
+ box_info->data = (void**)&mdata;
+ strcpy(box_info->file_path, file_path);
+ box_info->size = size;
+ memcpy(*box_info->data, data, size);
+
+ pthread_create(&thread_t, NULL, write_yuv_dump_to_file_thread, (void*)box_info);
+
+ fill_buffer();
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE hello_video2::_write_yuv_dump_to_file(const char *file_path, void *data, int size)
+{
+ FILE *fd;
+ int remainder;
+ int written;
+
+ fd = fopen(file_path, "wb");
+ if (!fd) {
+ fprintf(stderr, "open failed:%s\n", file_path);
+ return OMX_ErrorNone;
+ }
+
+ remainder = size;
+ while (remainder) {
+ written = fwrite(data, 1, remainder, fd);
+ remainder -= written;
+ }
+ fflush(fd);
+ fclose(fd);
+
+ fprintf(stderr, "saved yuv:%s\n", file_path);
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+OMX_ERRORTYPE hello_video2::fill_buffer(OMX_PTR pAppD, OMX_BUFFERHEADERTYPE *buffer)
+{
+ static int number = 0;
+ char file_path[128];
+
+ mkdir("/var/yuv", 0777);
+ sprintf(file_path, "/var/yuv/1280x544_yuv420p-%04d.yuv", number++);
+ write_yuv_dump_to_file(file_path, buffer->pBuffer, buffer->nFilledLen);
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE hello_video2::fill_buffer()
+{
+ OMX_BUFFERHEADERTYPE *out_buffer;
+
+ out_buffer = get_free_output_buffer();
+ OMX_FillThisBuffer(component, out_buffer);
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::port_settings_changed()
+{
+ fprintf(stderr, "PortSettingsChanged...\n");
+ if (output_buffer_header[0] != NULL)
+ {
+ OMX_SendCommand(component, OMX_CommandPortDisable, output_port_def.nPortIndex, NULL);
+ block_until_port_changed(component, output_port_def.nPortIndex, OMX_FALSE);
+ for (unsigned int i = 0; i < output_port_def.nBufferCountActual; ++i) {
+// tbm_bo_unref(output_buffer_header[i]->pBuffer);
+ OMX_FreeBuffer(component, 131, output_buffer_header[i]);
+ output_buffer_header[i] = NULL;
+ }
+ } else {
+ OMX_SendCommand(component, OMX_CommandPortDisable, output_port_def.nPortIndex, NULL);
+ block_until_port_changed(component, output_port_def.nPortIndex, OMX_FALSE);
+ }
+
+ get_port_parameters();
+
+ ErrorCode = OMX_SendCommand(component, OMX_CommandPortEnable, output_port_def.nPortIndex, NULL);
+ block_until_port_changed(component, output_port_def.nPortIndex, OMX_TRUE);
+
+ get_port_parameters();
+
+ output_buffer_usage = 0;
+ prepare_output_buffers(output_port_def.nBufferCountActual);
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::get_port_parameters()
+{
+ ErrorCode = OMX_ErrorNone;
+
+ ErrorCode = OMX_GetParameter(component, OMX_IndexParamPortDefinition, &input_port_def);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ };
+
+ ErrorCode = OMX_GetParameter(component, OMX_IndexParamPortDefinition, &output_port_def);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::set_port_parameters()
+{
+ ErrorCode = OMX_ErrorNone;
+ OMX_VIDEO_PARAM_PORTFORMATTYPE ovPort, ivPort;
+ memset(&ovPort, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+ ovPort.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ ovPort.nVersion.nVersion = OMX_VERSION;
+ ovPort.nPortIndex = 130;
+ ovPort.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ ErrorCode = OMX_SetParameter(component, OMX_IndexParamVideoPortFormat, &ovPort);
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Failed to set AVC coding type.\n");
+ }
+
+ memset(&ivPort, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
+ ivPort.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ ivPort.nVersion.nVersion = OMX_VERSION;
+ ivPort.nPortIndex = 131;
+ ivPort.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ ivPort.eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ ErrorCode = OMX_SetParameter(component, OMX_IndexParamVideoPortFormat, &ivPort);
+ if (ErrorCode != OMX_ErrorNone) {
+ printf("Failed to set color format.\n");
+ }
+
+ output_port_def.nBufferCountActual = 16;
+ ErrorCode = OMX_SetParameter(component, OMX_IndexParamPortDefinition, &output_port_def);
+ if (ErrorCode != OMX_ErrorNone) {
+ fprintf(stderr, "%s[%d]%s\n", __func__, __LINE__, OMX_strerror(ErrorCode));
+ }
+
+ return ErrorCode;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::prepare_input_buffers(unsigned int num)
+{
+ ErrorCode = OMX_ErrorNone;
+ unsigned int * pPrivateData;
+
+ for (unsigned int i = 0; i < num; i++)
+ {
+ pPrivateData = &input_buffer_number[i];
+ *pPrivateData = (1 << i);
+ input_buffer_usage |= *pPrivateData;
+ ErrorCode = OMX_AllocateBuffer(component, &input_buffer_header[i], 130, pPrivateData, input_port_def.nBufferSize);
+
+ if (ErrorCode == OMX_ErrorNone) {
+ fprintf(stderr, "Okay:prepare_input_buffers:Output buffer %u allocated,%d.\n", i + 1, input_port_def.nBufferSize);
+ }
+ else {
+ fprintf(stderr, "Err:prepare_input_buffers:%d. %s\n", i, OMX_strerror(ErrorCode));
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_ERRORTYPE hello_video2::prepare_output_buffers(unsigned int num)
+{
+ tbm_bo_handle handle_bo;
+ ErrorCode = OMX_ErrorNone;
+ tbm_bo tmp;
+ unsigned char *buf;
+ unsigned int *pPrivateData;
+
+ for (unsigned int i = 0; i < num; i++)
+ {
+ pPrivateData = &output_buffer_number[i];
+ *pPrivateData = (1 << i);
+ output_buffer_usage |= *pPrivateData;
+
+ tmp = tbm_bo_alloc(_tbm_bufmgr, output_port_def.nBufferSize, TBM_BO_WC);
+ handle_bo = tbm_bo_get_handle(tmp, TBM_DEVICE_CPU);
+ buf = (unsigned char*)handle_bo.ptr;
+
+ ErrorCode = OMX_UseBuffer(component, &output_buffer_header[i], output_port_def.nPortIndex, pPrivateData, output_port_def.nBufferSize, buf);
+
+ if (ErrorCode == OMX_ErrorNone) {
+ fprintf(stderr, "Okay:prepare_output_buffers:Output buffer %u allocated,%d.\n", i + 1, output_port_def.nBufferSize);
+ }
+ else {
+ fprintf(stderr, "Err:prepare_output_buffers:%d. %s\n", i, OMX_strerror(ErrorCode));
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+/******************************************************************************/
+
+OMX_BUFFERHEADERTYPE * hello_video2::get_free_input_buffer()
+{
+ while (true) {
+ for (unsigned int i = 0; i < input_port_def.nBufferCountActual; i++) {
+ if ((input_buffer_usage & *((unsigned int *)input_buffer_header[i]->pAppPrivate)) != 0) {
+ return input_buffer_header[i];
+ }
+ }
+ OMXWaitForEmpty();
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+OMX_BUFFERHEADERTYPE * hello_video2::get_free_output_buffer()
+{
+ while (true)
+ {
+ for (unsigned int i = 0; i < output_port_def.nBufferCountActual; i++) {
+ if ((output_buffer_usage & *((unsigned int *)output_buffer_header[i]->pAppPrivate)) != 0) {
+ return output_buffer_header[i];
+ }
+ }
+ OMXWaitForFilled();
+ }
+
+ return NULL;
+}
+
+
+/******************************************************************************/
+
+int main (int argc, char **argv)
+{
+ int size;
+ FILE * in = NULL;
+ unsigned char buff[500000];
+ hello_video2 client;
+
+ mutex_init();
+
+ if (pthread_create(&thread_t1, NULL, __port_settings_changed_thread, (void *)&client) < 0) {
+ fprintf(stderr, "thread1 create error:");
+ exit(0);
+ }
+
+ in = fopen(argv[1], "r");
+ if (in == NULL) {
+ printf("No such file.\n");
+ exit(0);
+ }
+
+ size = fread(buff, 1, 500000, in);
+ fclose(in);
+
+ client.decode_frame(buff, size);
+////////////////////////////////////////////////////////////////////
+// //
+// I dont worry form now. //
+// //
+////////////////////////////////////////////////////////////////////
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "bcm_host.h"
+#include <IL/OMX_Component.h>
+#include <IL/OMX_Types.h>
+#include <IL/OMX_Index.h>
+#include <IL/OMX_Broadcom.h>
+#include <IL/OMX_IVCommon.h>
+#include <tbm_type.h>
+#include <tbm_surface.h>
+#include <tbm_bufmgr.h>
+
+struct NALu
+{
+ unsigned int pos, size, type;
+ NALu(unsigned int p, unsigned int s, unsigned int t)
+ : pos(p), size(s), type(t)
+ { };
+
+ NALu() { };
+
+ ~NALu() { };
+};
+
+typedef struct
+{
+ char file_path[128];
+ unsigned int size;
+ void** data;
+} DUMP_FILE_INFO;
+
+pthread_mutex_t OMXMutex, OMXEmptyMutex, OMXFilledMutex, OMXPortSettingsChangedMutex;
+pthread_cond_t OMXStateCond, OMXEmptyCond, OMXFilledCond, OMXPortSettingsChangedCond;
+
+void mutex_init()
+{
+ if (pthread_mutex_init(&OMXMutex, NULL) != 0) {
+ printf("Can't init state mutex.\n");
+ }
+
+ if (pthread_mutex_init(&OMXEmptyMutex, NULL) != 0) {
+ printf("Can't init empty mutex.\n");
+ }
+
+ if (pthread_mutex_init(&OMXFilledMutex, NULL) != 0) {
+ printf("Can't init filled mutex.\n");
+ };
+
+ if (pthread_mutex_init(&OMXPortSettingsChangedMutex, NULL) != 0) {
+ printf("Can't init port settings changed mutex.\n");
+ }
+
+ OMXStateCond = PTHREAD_COND_INITIALIZER;
+ OMXEmptyCond = PTHREAD_COND_INITIALIZER;
+ OMXFilledCond = PTHREAD_COND_INITIALIZER;
+ OMXPortSettingsChangedCond = PTHREAD_COND_INITIALIZER;
+};
+
+/*****************************************************************************/
+
+struct hello_video2
+{
+public:
+ hello_video2();
+ ~hello_video2();
+
+ OMX_ERRORTYPE decode_frame(unsigned char * data, unsigned int size);
+ OMX_BUFFERHEADERTYPE * get_free_input_buffer();
+ OMX_BUFFERHEADERTYPE * get_free_output_buffer();
+ OMX_ERRORTYPE get_port_parameters();
+ OMX_ERRORTYPE set_state(OMX_STATETYPE nState);
+ OMX_ERRORTYPE set_port_parameters();
+ OMX_ERRORTYPE prepare_input_buffers(unsigned int num);
+ OMX_ERRORTYPE prepare_output_buffers(unsigned int num);
+ OMX_STATETYPE get_state();
+ OMX_ERRORTYPE block_until_port_changed(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL bEnabled);
+ OMX_ERRORTYPE port_settings_changed();
+ OMX_ERRORTYPE fill_buffer(OMX_PTR pAppD, OMX_BUFFERHEADERTYPE *buffer);
+ OMX_ERRORTYPE fill_buffer();
+ OMX_ERRORTYPE _write_yuv_dump_to_file(const char *file_path, void *data, int size);
+ OMX_ERRORTYPE write_yuv_dump_to_file(const char *file_path, void *data, int size);
+ const char* dump_compression_video_format(OMX_VIDEO_CODINGTYPE c);
+ const char* dump_compression_image_format(OMX_IMAGE_CODINGTYPE c);
+ const char* dump_color_format(OMX_COLOR_FORMATTYPE c);
+ void dump_portdef(OMX_PARAM_PORTDEFINITIONTYPE* portdef);
+ void dump_port(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL dumpformats);
+
+ static OMX_ERRORTYPE Init();
+ static OMX_ERRORTYPE DeInit();
+ static const char * OMX_strerror(OMX_ERRORTYPE errorCode);
+ static unsigned int FindAllNALu(unsigned char * source, unsigned int size, NALu * table);
+
+ friend OMX_ERRORTYPE eventHandler(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2, OMX_PTR eventData);
+ friend OMX_ERRORTYPE bufferEmptied(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_BUFFERHEADERTYPE * buffer);
+ friend OMX_ERRORTYPE bufferFilled(OMX_HANDLETYPE hComp, OMX_PTR pAppD, OMX_BUFFERHEADERTYPE * buffer);
+public:
+ tbm_bufmgr _tbm_bufmgr;
+ OMX_CALLBACKTYPE callback;
+ OMX_ERRORTYPE ErrorCode;
+ unsigned int input_buffer_usage;
+ unsigned int output_buffer_usage;
+ OMX_STATETYPE component_state;
+ OMX_HANDLETYPE component;
+ unsigned int input_buffer_number[20];
+ unsigned int output_buffer_number[20];
+ OMX_PARAM_PORTDEFINITIONTYPE input_port_def;
+ OMX_PARAM_PORTDEFINITIONTYPE output_port_def;
+ OMX_BUFFERHEADERTYPE* input_buffer_header[20];
+ OMX_BUFFERHEADERTYPE* output_buffer_header[100];
+};
+
+/*****************************************************************************/
+
+hello_video2 * phello_video2 = NULL;
+void OMXWaitForState(OMX_STATETYPE nState)
+{
+ pthread_mutex_lock(&OMXMutex);
+ while (phello_video2->component_state != nState) {
+ pthread_cond_wait(&OMXStateCond, &OMXMutex);
+ }
+ pthread_mutex_unlock(&OMXMutex);
+}
+void OMXWaitForEmpty()
+{
+ pthread_mutex_lock(&OMXEmptyMutex);
+ pthread_cond_wait(&OMXEmptyCond, &OMXEmptyMutex);
+ pthread_mutex_unlock(&OMXEmptyMutex);
+}
+void OMXWaitForFilled()
+{
+ pthread_mutex_lock(&OMXFilledMutex);
+ pthread_cond_wait(&OMXFilledCond, &OMXFilledMutex);
+ pthread_mutex_unlock(&OMXFilledMutex);
+}
+void OMXWakeUp(OMX_STATETYPE nState)
+{
+ pthread_mutex_lock(&OMXMutex);
+ phello_video2->component_state = nState;
+ pthread_cond_signal(&OMXStateCond);
+ pthread_mutex_unlock(&OMXMutex);
+}
+void OMXWakeUpEmpty()
+{
+ pthread_mutex_lock(&OMXEmptyMutex);
+ pthread_cond_signal(&OMXEmptyCond);
+ pthread_mutex_unlock(&OMXEmptyMutex);
+}
+void OMXWakeUpFilled()
+{
+ pthread_mutex_lock(&OMXFilledMutex);
+ pthread_cond_signal(&OMXFilledCond);
+ pthread_mutex_unlock(&OMXFilledMutex);
+}
+
+void OMWaitForXPortSettingsChanged()
+{
+ pthread_mutex_lock(&OMXPortSettingsChangedMutex);
+ pthread_cond_wait(&OMXPortSettingsChangedCond, &OMXPortSettingsChangedMutex);
+ pthread_mutex_unlock(&OMXPortSettingsChangedMutex);
+}
+
+void OMXWakeupPortSettingsChanged()
+{
+ pthread_mutex_lock(&OMXPortSettingsChangedMutex);
+ pthread_cond_signal(&OMXPortSettingsChangedCond);
+ pthread_mutex_unlock(&OMXPortSettingsChangedMutex);
+}
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+Name: hello_video2
+Version: 0.0.1
+Release: 0
+Summary: OpenMAX IL demos for Raspberry Pi
+Group: Development/Libraries
+License: APACHE
+Source0: %{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
+BuildRequires: libraspberrypi-devel
+BuildRequires: libraspberrypi
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: gcc-c++
+BuildRequires: glibc-devel
+
+%description
+OpenMAX IL demos for Raspberry Pi
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+make
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/opt/vc/test
+pushd %{buildroot}/opt/vc/test
+cp %{_builddir}/%{name}-%{version}/hello_video2_tizen ./hello_video2_tizen.bin
+cp %{_builddir}/%{name}-%{version}/hello_video2_normal ./hello_video2_normal.bin
+popd
+
+%post
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%manifest %{name}.manifest
+%license LICENSE
+/opt/vc/test/*