1044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat/* 2044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * Copyright (C) 2014 The Android Open Source Project 3044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * All rights reserved. 4044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * 5044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * Redistribution and use in source and binary forms, with or without 6044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * modification, are permitted provided that the following conditions 7044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * are met: 8044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * * Redistributions of source code must retain the above copyright 9044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * notice, this list of conditions and the following disclaimer. 10044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * * Redistributions in binary form must reproduce the above copyright 11044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * notice, this list of conditions and the following disclaimer in 12044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * the documentation and/or other materials provided with the 13044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * distribution. 14044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * 15044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat * SUCH DAMAGE. 27044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat */ 28044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 29044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat#include <stdio.h> 30044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat#include <stdint.h> 31044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat#include <assert.h> 32044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat#include <stdlib.h> 33044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 34044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat#include "mp4enc_api.h" 35044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 36044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat// Constants. 37044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhatenum { 38044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat kMaxWidth = 720, 39044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat kMaxHeight = 480, 40044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat kMaxFrameRate = 30, 41044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat kMaxBitrate = 2048, // in kbps. 42044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat kOutputBufferSize = 250 * 1024, 43044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat kIDRFrameRefreshIntervalInSec = 1, // in seconds. 44044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat}; 45044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 46044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhatint main(int argc, char *argv[]) { 47044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 48044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (argc < 8) { 49044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Usage %s <input yuv> <output file> <mode> <width> " 50044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat "<height> <frame rate> <bitrate in kbps>\n", argv[0]); 51044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "mode : h263 or mpeg4\n"); 52044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Max width %d\n", kMaxWidth); 53044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Max height %d\n", kMaxHeight); 54044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Max framerate %d\n", kMaxFrameRate); 55044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Max bitrate %d kbps\n", kMaxBitrate); 56044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 57044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 58044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 59044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Read mode. 60044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat bool isH263mode; 61044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (strcmp(argv[3], "mpeg4") == 0) { 62044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat isH263mode = false; 63044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } else if (strcmp(argv[3], "h263") == 0) { 64044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat isH263mode = true; 65044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } else { 66044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Unsupported mode %s\n", argv[3]); 67044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 68044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 69044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 70044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Read height and width. 71044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t width; 72044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t height; 73044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat width = atoi(argv[4]); 74044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat height = atoi(argv[5]); 75044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (width > kMaxWidth || height > kMaxHeight || width <= 0 || height <= 0) { 76044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Unsupported dimensions %dx%d\n", width, height); 77044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 78044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 79044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 80044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (width % 16 != 0 || height % 16 != 0) { 81044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Video frame size %dx%d must be a multiple of 16\n", 82044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat width, height); 83044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 84044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 85044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 86044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Read frame rate. 87044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t frameRate; 88044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat frameRate = atoi(argv[6]); 89044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (frameRate > kMaxFrameRate || frameRate <= 0) { 90044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Unsupported frame rate %d\n", frameRate); 91044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 92044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 93044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 94044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Read bitrate. 95044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t bitrate; 96044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat bitrate = atoi(argv[7]); 97044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (bitrate > kMaxBitrate || bitrate <= 0) { 98044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Unsupported bitrate %d\n", bitrate); 99044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 100044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 101044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 102044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Allocate input buffer. 103044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat uint8_t *inputBuf = (uint8_t *)malloc((width * height * 3) / 2); 104044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat assert(inputBuf != NULL); 105044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 106044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Allocate output buffer. 107044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat uint8_t *outputBuf = (uint8_t *)malloc(kOutputBufferSize); 108044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat assert(outputBuf != NULL); 109044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 110044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Open the input file. 111044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat FILE *fpInput = fopen(argv[1], "rb"); 112044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (fpInput == NULL) { 113044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Could not open %s\n", argv[1]); 114044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(inputBuf); 115044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(outputBuf); 116044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 117044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 118044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 119044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Open the output file. 120044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat FILE *fpOutput = fopen(argv[2], "wb"); 121044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (fpOutput == NULL) { 122044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Could not open %s\n", argv[2]); 123044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(inputBuf); 124044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(outputBuf); 125044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fclose(fpInput); 126044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 127044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 128044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 129044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Initialize the encoder parameters. 130044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat tagvideoEncOptions encParams; 131044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat memset(&encParams, 0, sizeof(tagvideoEncOptions)); 132044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (!PVGetDefaultEncOption(&encParams, 0)) { 133044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Failed to get default encoding parameters\n"); 134044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(inputBuf); 135044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(outputBuf); 136044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fclose(fpInput); 137044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fclose(fpOutput); 138044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 139044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 140044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 141044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (isH263mode == false) { 142044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.encMode = COMBINE_MODE_WITH_ERR_RES; 143044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } else { 144044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.encMode = H263_MODE; 145044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 146044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.encWidth[0] = width; 147044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.encHeight[0] = height; 148044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.encFrameRate[0] = frameRate; 149044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.rcType = VBR_1; 150044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.vbvDelay = 5.0f; 151044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.profile_level = CORE_PROFILE_LEVEL2; 152044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.packetSize = 32; 153044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.rvlcEnable = PV_OFF; 154044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.numLayers = 1; 155044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.timeIncRes = 1000; 156044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.tickPerSrc = encParams.timeIncRes / frameRate; 157044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 158044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.bitRate[0] = bitrate * 1024; 159044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.iQuant[0] = 15; 160044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.pQuant[0] = 12; 161044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.quantType[0] = 0; 162044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.noFrameSkipped = PV_OFF; 163044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 164044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t IDRFrameRefreshIntervalInSec = kIDRFrameRefreshIntervalInSec; 165044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (IDRFrameRefreshIntervalInSec == 0) { 166044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.intraPeriod = 1; // All I frames. 167044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } else { 168044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.intraPeriod = (IDRFrameRefreshIntervalInSec * frameRate); 169044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 170044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 171044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.numIntraMB = 0; 172044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.sceneDetect = PV_ON; 173044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.searchRange = 16; 174044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.mv8x8Enable = PV_OFF; 175044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.gobHeaderInterval = 0; 176044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.useACPred = PV_ON; 177044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat encParams.intraDCVlcTh = 0; 178044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 179044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Initialize the handle. 180044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat tagvideoEncControls handle; 181044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat memset(&handle, 0, sizeof(tagvideoEncControls)); 182044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 183044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Initialize the encoder. 184044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (!PVInitVideoEncoder(&handle, &encParams)) { 185044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Failed to initialize the encoder\n"); 186044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 187044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 188044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 189044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Generate the header. 190044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t headerLength = kOutputBufferSize; 191044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (!PVGetVolHeader(&handle, outputBuf, &headerLength, 0)) { 192044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Failed to get VOL header\n"); 193044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return EXIT_FAILURE; 194044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 195044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fwrite(outputBuf, 1, headerLength, fpOutput); 196044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 197044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Core loop. 198044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t retVal = EXIT_SUCCESS; 199044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t frameSize = (width * height * 3) / 2; 200044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t numFramesEncoded = 0; 201044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 202044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat while (1) { 203044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Read the input frame. 204044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t bytesRead; 205044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat bytesRead = fread(inputBuf, 1, frameSize, fpInput); 206044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (bytesRead != frameSize) { 207044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat break; // End of file. 208044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 209044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 210044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Encode the input frame. 211044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat VideoEncFrameIO vin, vout; 212044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat memset(&vin, 0, sizeof(vin)); 213044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat memset(&vout, 0, sizeof(vout)); 214044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat vin.height = height; // height is multiple of 16. 215044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat vin.pitch = width; // width is multiple of 16. 216044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat vin.timestamp = (numFramesEncoded * 1000) / frameRate; // in ms. 217044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat vin.yChan = inputBuf; 218044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat vin.uChan = vin.yChan + vin.height * vin.pitch; 219044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2); 220044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 221044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat uint32_t modTimeMs = 0; 222044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t nLayer = 0; 223044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat MP4HintTrack hintTrack; 224044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat int32_t dataLength = kOutputBufferSize; 225044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat if (!PVEncodeVideoFrame(&handle, &vin, &vout, 226044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat &modTimeMs, outputBuf, &dataLength, &nLayer) || 227044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat !PVGetHintTrack(&handle, &hintTrack)) { 228044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fprintf(stderr, "Failed to encode frame or get hink track at " 229044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat " frame %d\n", numFramesEncoded); 230044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat retVal = EXIT_FAILURE; 231044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat break; 232044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 233044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat PVGetOverrunBuffer(&handle); 234044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat numFramesEncoded++; 235044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 236044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Write the output. 237044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fwrite(outputBuf, 1, dataLength, fpOutput); 238044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat } 239044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 240044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Close input and output file. 241044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fclose(fpInput); 242044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat fclose(fpOutput); 243044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 244044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Free allocated memory. 245044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(inputBuf); 246044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat free(outputBuf); 247044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat 248044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat // Close encoder instance. 249044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat PVCleanUpVideoEncoder(&handle); 250044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat return retVal; 251044c6ae441f14102551c1ba918d02d5c8d12c21eAshok Bhat} 252