Merge "Support for writing output data to a provided callback function instead of a file"
diff --git a/include/media/stagefright/MPEG2TSWriter.h b/include/media/stagefright/MPEG2TSWriter.h
index f2c6505..e4c1c49 100644
--- a/include/media/stagefright/MPEG2TSWriter.h
+++ b/include/media/stagefright/MPEG2TSWriter.h
@@ -31,6 +31,10 @@
     MPEG2TSWriter(int fd);
     MPEG2TSWriter(const char *filename);
 
+    MPEG2TSWriter(
+            void *cookie,
+            ssize_t (*write)(void *cookie, const void *data, size_t size));
+
     virtual status_t addSource(const sp<MediaSource> &source);
     virtual status_t start(MetaData *param = NULL);
     virtual status_t stop();
@@ -51,6 +55,10 @@
     struct SourceInfo;
 
     FILE *mFile;
+
+    void *mWriteCookie;
+    ssize_t (*mWriteFunc)(void *cookie, const void *data, size_t size);
+
     sp<ALooper> mLooper;
     sp<AHandlerReflector<MPEG2TSWriter> > mReflector;
 
@@ -69,6 +77,8 @@
     void writeProgramMap();
     void writeAccessUnit(int32_t sourceIndex, const sp<ABuffer> &buffer);
 
+    ssize_t internalWrite(const void *data, size_t size);
+
     DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSWriter);
 };
 
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 4e4f289..02eeb40 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -466,6 +466,8 @@
 
 MPEG2TSWriter::MPEG2TSWriter(int fd)
     : mFile(fdopen(dup(fd), "wb")),
+      mWriteCookie(NULL),
+      mWriteFunc(NULL),
       mStarted(false),
       mNumSourcesDone(0),
       mNumTSPacketsWritten(0),
@@ -475,6 +477,21 @@
 
 MPEG2TSWriter::MPEG2TSWriter(const char *filename)
     : mFile(fopen(filename, "wb")),
+      mWriteCookie(NULL),
+      mWriteFunc(NULL),
+      mStarted(false),
+      mNumSourcesDone(0),
+      mNumTSPacketsWritten(0),
+      mNumTSPacketsBeforeMeta(0) {
+    init();
+}
+
+MPEG2TSWriter::MPEG2TSWriter(
+        void *cookie,
+        ssize_t (*write)(void *cookie, const void *data, size_t size))
+    : mFile(NULL),
+      mWriteCookie(cookie),
+      mWriteFunc(write),
       mStarted(false),
       mNumSourcesDone(0),
       mNumTSPacketsWritten(0),
@@ -483,7 +500,7 @@
 }
 
 void MPEG2TSWriter::init() {
-    CHECK(mFile != NULL);
+    CHECK(mFile != NULL || mWriteFunc != NULL);
 
     mLooper = new ALooper;
     mLooper->setName("MPEG2TSWriter");
@@ -502,8 +519,10 @@
     mLooper->unregisterHandler(mReflector->id());
     mLooper->stop();
 
-    fclose(mFile);
-    mFile = NULL;
+    if (mFile != NULL) {
+        fclose(mFile);
+        mFile = NULL;
+    }
 }
 
 status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
@@ -718,7 +737,7 @@
     static const unsigned kContinuityCounter = 5;
     buffer->data()[3] |= kContinuityCounter;
 
-    CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
 }
 
 void MPEG2TSWriter::writeProgramMap() {
@@ -794,7 +813,7 @@
     *ptr++ = 0x00;
     *ptr++ = 0x00;
 
-    CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
 }
 
 void MPEG2TSWriter::writeAccessUnit(
@@ -890,7 +909,7 @@
 
     memcpy(ptr, accessUnit->data(), copy);
 
-    CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
 
     size_t offset = copy;
     while (offset < accessUnit->size()) {
@@ -923,7 +942,7 @@
         }
 
         memcpy(ptr, accessUnit->data() + offset, copy);
-        CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile),
+        CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
                  buffer->size());
 
         offset += copy;
@@ -939,5 +958,13 @@
     }
 }
 
+ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
+    if (mFile != NULL) {
+        return fwrite(data, 1, size, mFile);
+    }
+
+    return (*mWriteFunc)(mWriteCookie, data, size);
+}
+
 }  // namespace android