MediaPuller.cpp revision 8060060217ff16cd67c8f6a15c649f44c343acf0
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), 375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mIsAudio(false), 385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mPaused(false) { 39a438123bd96c7faf145683876702387efe5628d9Andreas Huber sp<MetaData> meta = source->getFormat(); 40a438123bd96c7faf145683876702387efe5628d9Andreas Huber const char *mime; 41a438123bd96c7faf145683876702387efe5628d9Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 42a438123bd96c7faf145683876702387efe5628d9Andreas Huber 43a438123bd96c7faf145683876702387efe5628d9Andreas Huber mIsAudio = !strncasecmp(mime, "audio/", 6); 44e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 45e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 46e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberMediaPuller::~MediaPuller() { 47e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 48e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 49e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t MediaPuller::postSynchronouslyAndReturnError( 50e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<AMessage> &msg) { 51e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> response; 52e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = msg->postAndAwaitResponse(&response); 53e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 54e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 55e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 56e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 57e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 58e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (!response->findInt32("err", &err)) { 59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = OK; 60e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 62e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 63e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 64e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 65e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t MediaPuller::start() { 66e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return postSynchronouslyAndReturnError(new AMessage(kWhatStart, id())); 67e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 68e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 6996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid MediaPuller::stopAsync(const sp<AMessage> ¬ify) { 7096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> msg = new AMessage(kWhatStop, id()); 7196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->setMessage("notify", notify); 7296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->post(); 73e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 74e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 755131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid MediaPuller::pause() { 765131d127a042ee88f903370be88845dc8c9f8578Andreas Huber (new AMessage(kWhatPause, id()))->post(); 775131d127a042ee88f903370be88845dc8c9f8578Andreas Huber} 785131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 795131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid MediaPuller::resume() { 805131d127a042ee88f903370be88845dc8c9f8578Andreas Huber (new AMessage(kWhatResume, id()))->post(); 815131d127a042ee88f903370be88845dc8c9f8578Andreas Huber} 825131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 83e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubervoid MediaPuller::onMessageReceived(const sp<AMessage> &msg) { 84e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber switch (msg->what()) { 85e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatStart: 86e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber { 87af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber status_t err; 88af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber if (mIsAudio) { 89af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber // This atrocity causes AudioSource to deliver absolute 90af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber // systemTime() based timestamps (off by 1 us). 91af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber sp<MetaData> params = new MetaData; 92af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber params->setInt64(kKeyTime, 1ll); 93af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber err = mSource->start(params.get()); 94af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber } else { 95af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber err = mSource->start(); 968060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber if (err != OK) { 978060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber ALOGE("source failed to start w/ err %d", err); 988060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber } 99af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber } 100e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 10196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (err == OK) { 10296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber schedulePull(); 103e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 104e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 105e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> response = new AMessage; 106e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber response->setInt32("err", err); 107e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 108e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber uint32_t replyID; 109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 110e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber response->postReply(replyID); 111e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 112e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 11496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatStop: 11596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 11696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<MetaData> meta = mSource->getFormat(); 11796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const char *tmp; 11896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &tmp)); 11996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber AString mime = tmp; 12096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 12196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("MediaPuller(%s) stopping.", mime.c_str()); 12296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mSource->stop(); 12396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("MediaPuller(%s) stopped.", mime.c_str()); 12496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ++mPullGeneration; 12596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 12696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> notify; 12796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findMessage("notify", ¬ify)); 12896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->post(); 12996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 13096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 13196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 132e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber case kWhatPull: 133e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber { 134e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber int32_t generation; 135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(msg->findInt32("generation", &generation)); 136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (generation != mPullGeneration) { 138e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 139e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 140e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 141e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber MediaBuffer *mbuf; 142e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = mSource->read(&mbuf); 143e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 1445131d127a042ee88f903370be88845dc8c9f8578Andreas Huber if (mPaused) { 1455131d127a042ee88f903370be88845dc8c9f8578Andreas Huber if (err == OK) { 1465131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mbuf->release(); 1475131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mbuf = NULL; 1485131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 1495131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 1505131d127a042ee88f903370be88845dc8c9f8578Andreas Huber schedulePull(); 1515131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 1525131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 1535131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 154e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 155e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == ERROR_END_OF_STREAM) { 156e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGI("stream ended."); 157e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 158e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGE("error %d reading stream.", err); 159e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 161e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify = mNotify->dup(); 162e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setInt32("what", kWhatEOS); 163e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->post(); 164e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } else { 165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber int64_t timeUs; 166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ABuffer> accessUnit = new ABuffer(mbuf->range_length()); 169e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber memcpy(accessUnit->data(), 171e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber (const uint8_t *)mbuf->data() + mbuf->range_offset(), 172e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mbuf->range_length()); 173e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 174e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber accessUnit->meta()->setInt64("timeUs", timeUs); 175a438123bd96c7faf145683876702387efe5628d9Andreas Huber 176a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mIsAudio) { 177a438123bd96c7faf145683876702387efe5628d9Andreas Huber mbuf->release(); 178a438123bd96c7faf145683876702387efe5628d9Andreas Huber mbuf = NULL; 179a438123bd96c7faf145683876702387efe5628d9Andreas Huber } else { 180a438123bd96c7faf145683876702387efe5628d9Andreas Huber // video encoder will release MediaBuffer when done 181a438123bd96c7faf145683876702387efe5628d9Andreas Huber // with underlying data. 182a438123bd96c7faf145683876702387efe5628d9Andreas Huber accessUnit->meta()->setPointer("mediaBuffer", mbuf); 183a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 184e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 185e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify = mNotify->dup(); 186e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 187e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setInt32("what", kWhatAccessUnit); 188e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setBuffer("accessUnit", accessUnit); 189e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->post(); 190e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 19196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mbuf != NULL) { 19296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("posted mbuf %p", mbuf); 19396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 19496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 195e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber schedulePull(); 196e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 197e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber break; 198e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 199e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 2005131d127a042ee88f903370be88845dc8c9f8578Andreas Huber case kWhatPause: 2015131d127a042ee88f903370be88845dc8c9f8578Andreas Huber { 2025131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mPaused = true; 2035131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 2045131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 2055131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 2065131d127a042ee88f903370be88845dc8c9f8578Andreas Huber case kWhatResume: 2075131d127a042ee88f903370be88845dc8c9f8578Andreas Huber { 2085131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mPaused = false; 2095131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 2105131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 2115131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 212e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber default: 213e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber TRESPASS(); 214e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 215e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 216e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 217e1957358f11031a554c57d4fb46988dd6044acc1Andreas Hubervoid MediaPuller::schedulePull() { 218e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> msg = new AMessage(kWhatPull, id()); 219e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber msg->setInt32("generation", mPullGeneration); 220e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber msg->post(); 221e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 222e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 223e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} // namespace android 224e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 225