MediaPuller.cpp revision 96fc6cc65ca93009a759a3a874b82a35771b9714
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 6896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid MediaPuller::stopAsync(const sp<AMessage> ¬ify) { 6996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> msg = new AMessage(kWhatStop, id()); 7096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->setMessage("notify", notify); 7196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->post(); 72e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 73e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 74e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubervoid MediaPuller::onMessageReceived(const sp<AMessage> &msg) { 75e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber switch (msg->what()) { 76e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatStart: 77e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber { 7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber status_t err = mSource->start(); 79e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 8096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (err == OK) { 8196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber schedulePull(); 82e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 83e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 84e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> response = new AMessage; 85e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber response->setInt32("err", err); 86e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 87e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber uint32_t replyID; 88e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 89e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 90e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber response->postReply(replyID); 91e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 92e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 93e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 9496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatStop: 9596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 9696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<MetaData> meta = mSource->getFormat(); 9796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const char *tmp; 9896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &tmp)); 9996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber AString mime = tmp; 10096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 10196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("MediaPuller(%s) stopping.", mime.c_str()); 10296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mSource->stop(); 10396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("MediaPuller(%s) stopped.", mime.c_str()); 10496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ++mPullGeneration; 10596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 10696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> notify; 10796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findMessage("notify", ¬ify)); 10896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->post(); 10996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 11096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 11196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 112e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatPull: 113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber { 114e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber int32_t generation; 115e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(msg->findInt32("generation", &generation)); 116e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 117e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (generation != mPullGeneration) { 118e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 119e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 120e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 121e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber MediaBuffer *mbuf; 122e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = mSource->read(&mbuf); 123e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 124e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 125e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == ERROR_END_OF_STREAM) { 126e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGI("stream ended."); 127e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 128e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGE("error %d reading stream.", err); 129e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 130e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 131e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify = mNotify->dup(); 132e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setInt32("what", kWhatEOS); 133e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->post(); 134e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber int64_t timeUs; 136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 138e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ABuffer> accessUnit = new ABuffer(mbuf->range_length()); 139e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 140e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber memcpy(accessUnit->data(), 141e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber (const uint8_t *)mbuf->data() + mbuf->range_offset(), 142e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mbuf->range_length()); 143e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 144e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber accessUnit->meta()->setInt64("timeUs", timeUs); 145a438123bd96c7faf145683876702387efe5628d9Andreas Huber 146a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mIsAudio) { 147a438123bd96c7faf145683876702387efe5628d9Andreas Huber mbuf->release(); 148a438123bd96c7faf145683876702387efe5628d9Andreas Huber mbuf = NULL; 149a438123bd96c7faf145683876702387efe5628d9Andreas Huber } else { 150a438123bd96c7faf145683876702387efe5628d9Andreas Huber // video encoder will release MediaBuffer when done 151a438123bd96c7faf145683876702387efe5628d9Andreas Huber // with underlying data. 152a438123bd96c7faf145683876702387efe5628d9Andreas Huber accessUnit->meta()->setPointer("mediaBuffer", mbuf); 153a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 154e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 155e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify = mNotify->dup(); 156e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 157e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setInt32("what", kWhatAccessUnit); 158e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setBuffer("accessUnit", accessUnit); 159e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->post(); 160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 16196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mbuf != NULL) { 16296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("posted mbuf %p", mbuf); 16396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 16496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber schedulePull(); 166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 169e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber default: 171e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber TRESPASS(); 172e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 173e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 174e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 175e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubervoid MediaPuller::schedulePull() { 176e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> msg = new AMessage(kWhatPull, id()); 177e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber msg->setInt32("generation", mPullGeneration); 178e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber msg->post(); 179e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 180e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 181e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} // namespace android 182e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 183