| /** |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| #include <stdlib.h> |
| #include "../includes/common.h" |
| |
| // This PoC is only for 32-bit builds |
| #if _32_BIT |
| #include "mp4dec_api.h" |
| |
| #define START_CODE 0xB0010000 |
| #define SIZE 0x100 |
| #define REF_YUV_SIZE 1000 |
| #define WIDTH 0x80 |
| #define HEIGHT 0x60 |
| |
| void clean_exit(uint8_t *frame, tagvideoDecControls *controls) { |
| delete frame; |
| delete controls; |
| } |
| #endif /* _32_BIT */ |
| |
| int main(int argc, char *argv[]) { |
| (void)argc; |
| (void)argv; |
| |
| // This PoC is only for 32-bit builds |
| #if _32_BIT |
| uint8 refYUV[REF_YUV_SIZE]; |
| FILE *fp = nullptr; |
| uint8_t *frame = nullptr; |
| unsigned int frameSize = 0; |
| tagvideoDecControls *controls = nullptr; |
| uint8_t *volData[1]; |
| int32_t volSize = 0; |
| |
| if (argc != 2) { |
| return EXIT_FAILURE; |
| } |
| |
| fp = fopen(argv[1], "rb"); |
| if (!fp) { |
| return EXIT_FAILURE; |
| } |
| |
| fseek(fp, 0, SEEK_END); |
| frameSize = ftell(fp); |
| fseek(fp, 0, SEEK_SET); |
| frame = new uint8_t[frameSize]; |
| fread(frame, sizeof(uint8_t), frameSize, fp); |
| fclose(fp); |
| fp = nullptr; |
| |
| controls = new tagvideoDecControls; |
| memset(controls, 0, sizeof(tagvideoDecControls)); |
| |
| int size = SIZE; |
| |
| uint32_t *volHeader = (uint32_t *) (frame); |
| if (*volHeader == START_CODE) { |
| PVCleanUpVideoDecoder(controls); |
| volData[0] = frame; |
| volSize = size; |
| } else { |
| volData[0] = nullptr; |
| volSize = 0; |
| size = 0; |
| } |
| |
| if (!PVInitVideoDecoder(controls, volData, &volSize, 1, WIDTH, HEIGHT, |
| MPEG4_MODE)) { |
| clean_exit(frame, controls); |
| return EXIT_FAILURE; |
| } |
| |
| MP4DecodingMode actualMode = PVGetDecBitstreamMode(controls); |
| if (actualMode != MPEG4_MODE) { |
| clean_exit(frame, controls); |
| return EXIT_FAILURE; |
| } |
| |
| PVSetPostProcType((VideoDecControls *) controls, 0); |
| PVSetReferenceYUV(controls, refYUV); |
| |
| uint8_t *bitstreamTmp = frame + size; |
| uint32_t timestamp = 0xFFFFFFFF; |
| int32_t tmp = frameSize - size; |
| VopHeaderInfo headerInfo; |
| uint32_t useExtTimestamp = 1; |
| if (PVDecodeVopHeader(controls, &bitstreamTmp, ×tamp, &tmp, |
| &headerInfo, &useExtTimestamp, refYUV) != PV_TRUE) { |
| clean_exit(frame, controls); |
| return EXIT_FAILURE; |
| } |
| |
| if (PVDecodeVopBody(controls, &tmp) != PV_TRUE) { |
| clean_exit(frame, controls); |
| return EXIT_FAILURE; |
| } |
| |
| clean_exit(frame, controls); |
| #endif /* _32_BIT */ |
| |
| return EXIT_SUCCESS; |
| } |