1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MEDIA_WRITER_H_
18 
19 #define MEDIA_WRITER_H_
20 
21 #include <utils/RefBase.h>
22 #include <media/stagefright/MediaSource.h>
23 #include <media/IMediaRecorderClient.h>
24 #include <media/mediarecorder.h>
25 
26 namespace android {
27 
28 struct MediaWriter : public RefBase {
MediaWriterMediaWriter29     MediaWriter()
30         : mMaxFileSizeLimitBytes(0),
31           mMaxFileDurationLimitUs(0) {
32     }
33 
34     // Returns true if the file descriptor is opened using a mode
35     // which meets minimum writer/muxer requirements.
isFdOpenModeValidMediaWriter36     static bool isFdOpenModeValid(int fd) {
37         // check for invalid file descriptor.
38         int flags = fcntl(fd, F_GETFL);
39         if (flags == -1) {
40             ALOGE("Invalid File Status Flags and/or mode : %d", flags);
41             return false;
42         }
43         // fd must be in read-write mode or write-only mode.
44         if ((flags & (O_RDWR | O_WRONLY)) == 0) {
45             ALOGE("File must be writable");
46             return false;
47         }
48         // Verify fd is seekable
49         off64_t off = lseek64(fd, 0, SEEK_SET);
50         if (off < 0) {
51             ALOGE("File descriptor is not seekable");
52             return false;
53         }
54         return true;
55     }
56 
57     // Returns true if the sample data is valid.
isSampleMetadataValidMediaWriter58     virtual bool isSampleMetadataValid([[maybe_unused]] size_t trackIndex,
59                                        [[maybe_unused]] int64_t timeUs) {
60         return true;
61     }
62 
63     virtual status_t addSource(const sp<MediaSource> &source) = 0;
64     virtual bool reachedEOS() = 0;
65     virtual status_t start(MetaData *params = NULL) = 0;
66     virtual status_t stop() = 0;
67     virtual status_t pause() = 0;
setCaptureRateMediaWriter68     virtual status_t setCaptureRate(float /* captureFps */) {
69         ALOG(LOG_WARN, "MediaWriter", "setCaptureRate unsupported");
70         return ERROR_UNSUPPORTED;
71     }
72 
setMaxFileSizeMediaWriter73     virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; }
setMaxFileDurationMediaWriter74     virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; }
setListenerMediaWriter75     virtual void setListener(const sp<IMediaRecorderClient>& listener) {
76         mListener = listener;
77     }
78 
dumpMediaWriter79     virtual status_t dump(int /*fd*/, const Vector<String16>& /*args*/) {
80         return OK;
81     }
82 
setStartTimeOffsetMsMediaWriter83     virtual void setStartTimeOffsetMs(int /*ms*/) {}
getStartTimeOffsetMsMediaWriter84     virtual int32_t getStartTimeOffsetMs() const { return 0; }
setNextFdMediaWriter85     virtual status_t setNextFd(int /*fd*/) { return INVALID_OPERATION; }
updateCVODegreesMediaWriter86     virtual void updateCVODegrees(int32_t /*cvoDegrees*/) {}
updatePayloadTypeMediaWriter87     virtual void updatePayloadType(int32_t /*payloadType*/) {}
updateSocketNetworkMediaWriter88     virtual void updateSocketNetwork(int64_t /*socketNetwork*/) {}
getSequenceNumMediaWriter89     virtual uint32_t getSequenceNum() { return 0; }
getAccumulativeBytesMediaWriter90     virtual uint64_t getAccumulativeBytes() { return 0; }
91 
92 protected:
~MediaWriterMediaWriter93     virtual ~MediaWriter() {}
94     int64_t mMaxFileSizeLimitBytes;
95     int64_t mMaxFileDurationLimitUs;
96     sp<IMediaRecorderClient> mListener;
97 
notifyMediaWriter98     void notify(int msg, int ext1, int ext2) {
99         if (msg == MEDIA_RECORDER_TRACK_EVENT_INFO || msg == MEDIA_RECORDER_TRACK_EVENT_ERROR) {
100             uint32_t trackId = (ext1 >> 28) & 0xf;
101             int type = ext1 & 0xfffffff;
102             ALOG(LOG_VERBOSE, "MediaWriter", "Track event err/info msg:%d, trackId:%u, type:%d,"
103                                              "val:%d", msg, trackId, type, ext2);
104         } else {
105             ALOG(LOG_VERBOSE, "MediaWriter", "Recorder event msg:%d, ext1:%d, ext2:%d",
106                                               msg, ext1, ext2);
107         }
108         if (mListener != nullptr) {
109             mListener->notify(msg, ext1, ext2);
110         }
111     }
112 private:
113     MediaWriter(const MediaWriter &);
114     MediaWriter &operator=(const MediaWriter &);
115 };
116 
117 }  // namespace android
118 
119 #endif  // MEDIA_WRITER_H_
120