MediaPuller.cpp revision a438123bd96c7faf145683876702387efe5628d9
1e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber/* 2e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * Copyright 2012, The Android Open Source Project 3e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * 4e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * you may not use this file except in compliance with the License. 6e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * You may obtain a copy of the License at 7e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * 8e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * 10e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * Unless required by applicable law or agreed to in writing, software 11e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * See the License for the specific language governing permissions and 14e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber * limitations under the License. 15e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber */ 16e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 17e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber//#define LOG_NDEBUG 0 18e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#define LOG_TAG "MediaPuller" 19e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <utils/Log.h> 20e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 21e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include "MediaPuller.h" 22e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 23e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 24e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <media/stagefright/foundation/ADebug.h> 25e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <media/stagefright/foundation/AMessage.h> 26e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <media/stagefright/MediaBuffer.h> 27e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <media/stagefright/MediaSource.h> 28e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include <media/stagefright/MetaData.h> 29e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 30e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubernamespace android { 31e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 32e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberMediaPuller::MediaPuller( 33e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaSource> &source, const sp<AMessage> ¬ify) 34e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber : mSource(source), 35e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mNotify(notify), 36a438123bd96c7faf145683876702387efe5628d9Andreas Huber mPullGeneration(0), 37a438123bd96c7faf145683876702387efe5628d9Andreas Huber mIsAudio(false) { 38a438123bd96c7faf145683876702387efe5628d9Andreas Huber sp<MetaData> meta = source->getFormat(); 39a438123bd96c7faf145683876702387efe5628d9Andreas Huber const char *mime; 40a438123bd96c7faf145683876702387efe5628d9Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 41a438123bd96c7faf145683876702387efe5628d9Andreas Huber 42a438123bd96c7faf145683876702387efe5628d9Andreas Huber mIsAudio = !strncasecmp(mime, "audio/", 6); 43e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 44e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 45e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberMediaPuller::~MediaPuller() { 46e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 47e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 48e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t MediaPuller::postSynchronouslyAndReturnError( 49e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<AMessage> &msg) { 50e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> response; 51e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 52e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 53e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 54e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 55e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 56e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 57e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (!response->findInt32("err", &err)) { 58e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = OK; 59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 60e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 62e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 63e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 64e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t MediaPuller::start() { 65e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return postSynchronouslyAndReturnError(new AMessage(kWhatStart, id())); 66e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 67e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 68e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t MediaPuller::stop() { 69e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return postSynchronouslyAndReturnError(new AMessage(kWhatStop, id())); 70e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 71e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 72e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubervoid MediaPuller::onMessageReceived(const sp<AMessage> &msg) { 73e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber switch (msg->what()) { 74e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatStart: 75e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatStop: 76e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber { 77e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err; 78e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 79e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (msg->what() == kWhatStart) { 80e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mSource->start(); 81e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 82e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == OK) { 83e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber schedulePull(); 84e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 85e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 86a438123bd96c7faf145683876702387efe5628d9Andreas Huber sp<MetaData> meta = mSource->getFormat(); 87a438123bd96c7faf145683876702387efe5628d9Andreas Huber const char *tmp; 88a438123bd96c7faf145683876702387efe5628d9Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &tmp)); 89a438123bd96c7faf145683876702387efe5628d9Andreas Huber AString mime = tmp; 90a438123bd96c7faf145683876702387efe5628d9Andreas Huber 91a438123bd96c7faf145683876702387efe5628d9Andreas Huber ALOGI("MediaPuller(%s) stopping.", mime.c_str()); 92e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mSource->stop(); 93a438123bd96c7faf145683876702387efe5628d9Andreas Huber ALOGI("MediaPuller(%s) stopped.", mime.c_str()); 94e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ++mPullGeneration; 95e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 96e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 97e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> response = new AMessage; 98e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber response->setInt32("err", err); 99e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 100e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber uint32_t replyID; 101e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 102e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 103e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber response->postReply(replyID); 104e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 105e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 106e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 107e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatPull: 108e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber { 109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber int32_t generation; 110e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(msg->findInt32("generation", &generation)); 111e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 112e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (generation != mPullGeneration) { 113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 114e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 115e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 116e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber MediaBuffer *mbuf; 117e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = mSource->read(&mbuf); 118e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 119e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 120e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == ERROR_END_OF_STREAM) { 121e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGI("stream ended."); 122e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 123e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGE("error %d reading stream.", err); 124e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 125e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 126e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify = mNotify->dup(); 127e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setInt32("what", kWhatEOS); 128e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->post(); 129e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 130e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber int64_t timeUs; 131e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 132e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 133e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ABuffer> accessUnit = new ABuffer(mbuf->range_length()); 134e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber memcpy(accessUnit->data(), 136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber (const uint8_t *)mbuf->data() + mbuf->range_offset(), 137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mbuf->range_length()); 138e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 139e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber accessUnit->meta()->setInt64("timeUs", timeUs); 140a438123bd96c7faf145683876702387efe5628d9Andreas Huber 141a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mIsAudio) { 142a438123bd96c7faf145683876702387efe5628d9Andreas Huber mbuf->release(); 143a438123bd96c7faf145683876702387efe5628d9Andreas Huber mbuf = NULL; 144a438123bd96c7faf145683876702387efe5628d9Andreas Huber } else { 145a438123bd96c7faf145683876702387efe5628d9Andreas Huber // video encoder will release MediaBuffer when done 146a438123bd96c7faf145683876702387efe5628d9Andreas Huber // with underlying data. 147a438123bd96c7faf145683876702387efe5628d9Andreas Huber accessUnit->meta()->setPointer("mediaBuffer", mbuf); 148a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 149e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 150e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify = mNotify->dup(); 151e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 152e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setInt32("what", kWhatAccessUnit); 153e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setBuffer("accessUnit", accessUnit); 154e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->post(); 155e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 156e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber schedulePull(); 157e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 158e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 159e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 161e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber default: 162e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber TRESPASS(); 163e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 164e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubervoid MediaPuller::schedulePull() { 167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> msg = new AMessage(kWhatPull, id()); 168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber msg->setInt32("generation", mPullGeneration); 169e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber msg->post(); 170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 171e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 172e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} // namespace android 173e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 174