16ac391b3SStephan Aßmus /* 26ac391b3SStephan Aßmus * Copyright 2009, Stephan Aßmus <superstippi@gmx.de> 36ac391b3SStephan Aßmus * All rights reserved. Distributed under the terms of the GNU L-GPL license. 46ac391b3SStephan Aßmus */ 56ac391b3SStephan Aßmus 66ac391b3SStephan Aßmus #include "AVFormatWriter.h" 76ac391b3SStephan Aßmus 86ac391b3SStephan Aßmus #include <stdio.h> 96ac391b3SStephan Aßmus #include <string.h> 106ac391b3SStephan Aßmus #include <stdlib.h> 116ac391b3SStephan Aßmus 126ac391b3SStephan Aßmus #include <new> 136ac391b3SStephan Aßmus 146ac391b3SStephan Aßmus #include <AutoDeleter.h> 156ac391b3SStephan Aßmus #include <Autolock.h> 166ac391b3SStephan Aßmus #include <ByteOrder.h> 176ac391b3SStephan Aßmus #include <DataIO.h> 186ac391b3SStephan Aßmus #include <MediaDefs.h> 196ac391b3SStephan Aßmus #include <MediaFormats.h> 206ac391b3SStephan Aßmus 216ac391b3SStephan Aßmus extern "C" { 226ac391b3SStephan Aßmus #include "avformat.h" 236ac391b3SStephan Aßmus } 246ac391b3SStephan Aßmus 256ac391b3SStephan Aßmus #include "DemuxerTable.h" 266ac391b3SStephan Aßmus #include "gfx_util.h" 276ac391b3SStephan Aßmus 286ac391b3SStephan Aßmus 296ac391b3SStephan Aßmus #define TRACE_AVFORMAT_WRITER 306ac391b3SStephan Aßmus #ifdef TRACE_AVFORMAT_WRITER 316ac391b3SStephan Aßmus # define TRACE printf 326ac391b3SStephan Aßmus # define TRACE_IO(a...) 336ac391b3SStephan Aßmus # define TRACE_PACKET(a...) 346ac391b3SStephan Aßmus #else 356ac391b3SStephan Aßmus # define TRACE(a...) 366ac391b3SStephan Aßmus # define TRACE_IO(a...) 376ac391b3SStephan Aßmus # define TRACE_PACKET(a...) 386ac391b3SStephan Aßmus #endif 396ac391b3SStephan Aßmus 406ac391b3SStephan Aßmus #define ERROR(a...) fprintf(stderr, a) 416ac391b3SStephan Aßmus 426ac391b3SStephan Aßmus 436ac391b3SStephan Aßmus // #pragma mark - AVFormatWriter::StreamCookie 446ac391b3SStephan Aßmus 456ac391b3SStephan Aßmus 466ac391b3SStephan Aßmus class AVFormatWriter::StreamCookie { 476ac391b3SStephan Aßmus public: 486ac391b3SStephan Aßmus StreamCookie(BPositionIO* target, 496ac391b3SStephan Aßmus BLocker* streamLock); 506ac391b3SStephan Aßmus virtual ~StreamCookie(); 516ac391b3SStephan Aßmus 526ac391b3SStephan Aßmus private: 536ac391b3SStephan Aßmus BPositionIO* fTarget; 546ac391b3SStephan Aßmus off_t fPosition; 556ac391b3SStephan Aßmus // Since different threads may read from the source, 566ac391b3SStephan Aßmus // we need to protect the file position and I/O by a lock. 576ac391b3SStephan Aßmus BLocker* fStreamLock; 586ac391b3SStephan Aßmus }; 596ac391b3SStephan Aßmus 606ac391b3SStephan Aßmus 616ac391b3SStephan Aßmus 626ac391b3SStephan Aßmus AVFormatWriter::StreamCookie::StreamCookie(BPositionIO* target, 636ac391b3SStephan Aßmus BLocker* streamLock) 646ac391b3SStephan Aßmus : 656ac391b3SStephan Aßmus fTarget(target), 666ac391b3SStephan Aßmus fPosition(0), 676ac391b3SStephan Aßmus fStreamLock(streamLock) 686ac391b3SStephan Aßmus { 696ac391b3SStephan Aßmus } 706ac391b3SStephan Aßmus 716ac391b3SStephan Aßmus 726ac391b3SStephan Aßmus AVFormatWriter::StreamCookie::~StreamCookie() 736ac391b3SStephan Aßmus { 746ac391b3SStephan Aßmus } 756ac391b3SStephan Aßmus 766ac391b3SStephan Aßmus 776ac391b3SStephan Aßmus // #pragma mark - AVFormatWriter 786ac391b3SStephan Aßmus 796ac391b3SStephan Aßmus 806ac391b3SStephan Aßmus AVFormatWriter::AVFormatWriter() 816ac391b3SStephan Aßmus : 826ac391b3SStephan Aßmus fStreams(NULL), 836ac391b3SStephan Aßmus fStreamLock("stream lock") 846ac391b3SStephan Aßmus { 856ac391b3SStephan Aßmus TRACE("AVFormatWriter::AVFormatWriter\n"); 866ac391b3SStephan Aßmus } 876ac391b3SStephan Aßmus 886ac391b3SStephan Aßmus 896ac391b3SStephan Aßmus AVFormatWriter::~AVFormatWriter() 906ac391b3SStephan Aßmus { 916ac391b3SStephan Aßmus TRACE("AVFormatWriter::~AVFormatWriter\n"); 926ac391b3SStephan Aßmus if (fStreams != NULL) { 936ac391b3SStephan Aßmus delete fStreams[0]; 946ac391b3SStephan Aßmus delete[] fStreams; 956ac391b3SStephan Aßmus } 966ac391b3SStephan Aßmus } 976ac391b3SStephan Aßmus 986ac391b3SStephan Aßmus 996ac391b3SStephan Aßmus // #pragma mark - 1006ac391b3SStephan Aßmus 1016ac391b3SStephan Aßmus 1026ac391b3SStephan Aßmus status_t 1036ac391b3SStephan Aßmus AVFormatWriter::SetCopyright(const char* copyright) 1046ac391b3SStephan Aßmus { 1056ac391b3SStephan Aßmus TRACE("AVFormatWriter::SetCopyright(%s)\n", copyright); 1066ac391b3SStephan Aßmus 1076ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 1086ac391b3SStephan Aßmus } 1096ac391b3SStephan Aßmus 1106ac391b3SStephan Aßmus 1116ac391b3SStephan Aßmus status_t 1126ac391b3SStephan Aßmus AVFormatWriter::CommitHeader() 1136ac391b3SStephan Aßmus { 1146ac391b3SStephan Aßmus TRACE("AVFormatWriter::CommitHeader\n"); 1156ac391b3SStephan Aßmus 1166ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 1176ac391b3SStephan Aßmus } 1186ac391b3SStephan Aßmus 1196ac391b3SStephan Aßmus 1206ac391b3SStephan Aßmus status_t 1216ac391b3SStephan Aßmus AVFormatWriter::Flush() 1226ac391b3SStephan Aßmus { 1236ac391b3SStephan Aßmus TRACE("AVFormatWriter::Flush\n"); 1246ac391b3SStephan Aßmus 1256ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 1266ac391b3SStephan Aßmus } 1276ac391b3SStephan Aßmus 1286ac391b3SStephan Aßmus 1296ac391b3SStephan Aßmus status_t 1306ac391b3SStephan Aßmus AVFormatWriter::Close() 1316ac391b3SStephan Aßmus { 1326ac391b3SStephan Aßmus TRACE("AVFormatWriter::Close\n"); 1336ac391b3SStephan Aßmus 1346ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 1356ac391b3SStephan Aßmus } 1366ac391b3SStephan Aßmus 1376ac391b3SStephan Aßmus 1386ac391b3SStephan Aßmus status_t 1396ac391b3SStephan Aßmus AVFormatWriter::AllocateCookie(void** _cookie) 1406ac391b3SStephan Aßmus { 1416ac391b3SStephan Aßmus TRACE("AVFormatWriter::AllocateCookie()\n"); 1426ac391b3SStephan Aßmus 1436ac391b3SStephan Aßmus BAutolock _(fStreamLock); 1446ac391b3SStephan Aßmus 1456ac391b3SStephan Aßmus if (fStreams == NULL) 1466ac391b3SStephan Aßmus return B_NO_INIT; 1476ac391b3SStephan Aßmus 1486ac391b3SStephan Aßmus if (_cookie == NULL) 1496ac391b3SStephan Aßmus return B_BAD_VALUE; 1506ac391b3SStephan Aßmus 1516ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 1526ac391b3SStephan Aßmus } 1536ac391b3SStephan Aßmus 1546ac391b3SStephan Aßmus 1556ac391b3SStephan Aßmus status_t 1566ac391b3SStephan Aßmus AVFormatWriter::FreeCookie(void* _cookie) 1576ac391b3SStephan Aßmus { 1586ac391b3SStephan Aßmus BAutolock _(fStreamLock); 1596ac391b3SStephan Aßmus 1606ac391b3SStephan Aßmus StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie); 1616ac391b3SStephan Aßmus 1626ac391b3SStephan Aßmus if (cookie != NULL) { 1636ac391b3SStephan Aßmus // if (fStreams != NULL) 1646ac391b3SStephan Aßmus // fStreams[cookie->VirtualIndex()] = NULL; 1656ac391b3SStephan Aßmus delete cookie; 1666ac391b3SStephan Aßmus } 1676ac391b3SStephan Aßmus 1686ac391b3SStephan Aßmus return B_OK; 1696ac391b3SStephan Aßmus } 1706ac391b3SStephan Aßmus 1716ac391b3SStephan Aßmus 1726ac391b3SStephan Aßmus // #pragma mark - 1736ac391b3SStephan Aßmus 1746ac391b3SStephan Aßmus 1756ac391b3SStephan Aßmus status_t 176fa770e4cSStephan Aßmus AVFormatWriter::SetCopyright(void* cookie, const char* copyright) 177fa770e4cSStephan Aßmus { 178fa770e4cSStephan Aßmus TRACE("AVFormatWriter::SetCopyright(%p, %s)\n", cookie, copyright); 179fa770e4cSStephan Aßmus 180fa770e4cSStephan Aßmus return B_NOT_SUPPORTED; 181fa770e4cSStephan Aßmus } 182fa770e4cSStephan Aßmus 183fa770e4cSStephan Aßmus 184fa770e4cSStephan Aßmus status_t 1856ac391b3SStephan Aßmus AVFormatWriter::AddTrackInfo(void* cookie, uint32 code, 1866ac391b3SStephan Aßmus const void* data, size_t size, uint32 flags) 1876ac391b3SStephan Aßmus { 1886ac391b3SStephan Aßmus TRACE("AVFormatWriter::AddTrackInfo(%lu, %p, %ld, %lu)\n", 1896ac391b3SStephan Aßmus code, data, size, flags); 1906ac391b3SStephan Aßmus 1916ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 1926ac391b3SStephan Aßmus } 1936ac391b3SStephan Aßmus 1946ac391b3SStephan Aßmus 1956ac391b3SStephan Aßmus status_t 196c98ea335SStephan Aßmus AVFormatWriter::WriteChunk(void* cookie, const void* chunkBuffer, 197fa770e4cSStephan Aßmus size_t chunkSize, media_encode_info* encodeInfo) 1986ac391b3SStephan Aßmus { 199fa770e4cSStephan Aßmus TRACE("AVFormatWriter::WriteChunk(%p, %ld, %p)\n", chunkBuffer, chunkSize, 200fa770e4cSStephan Aßmus encodeInfo); 2016ac391b3SStephan Aßmus 2026ac391b3SStephan Aßmus return B_NOT_SUPPORTED; 2036ac391b3SStephan Aßmus } 2046ac391b3SStephan Aßmus 2056ac391b3SStephan Aßmus 206*2e9d65abSStephan Aßmus // #pragma mark - 207*2e9d65abSStephan Aßmus 208*2e9d65abSStephan Aßmus 209*2e9d65abSStephan Aßmus /*static*/ int 210*2e9d65abSStephan Aßmus AVFormatWriter::_Write(void* cookie, const uint8* buffer, int bufferSize) 211*2e9d65abSStephan Aßmus { 212*2e9d65abSStephan Aßmus TRACE_IO("AVFormatWriter::_Write(%p, %p, %d)\n", 213*2e9d65abSStephan Aßmus cookie, buffer, bufferSize); 214*2e9d65abSStephan Aßmus 215*2e9d65abSStephan Aßmus AVFormatWriter* writer = reinterpret_cast<AVFormatWriter*>(cookie); 216*2e9d65abSStephan Aßmus 217*2e9d65abSStephan Aßmus ssize_t written = writer->fTarget->Write(buffer, bufferSize); 218*2e9d65abSStephan Aßmus 219*2e9d65abSStephan Aßmus TRACE_IO(" written: %ld\n", written); 220*2e9d65abSStephan Aßmus return (int)written; 221*2e9d65abSStephan Aßmus 222*2e9d65abSStephan Aßmus } 223*2e9d65abSStephan Aßmus 224*2e9d65abSStephan Aßmus 225*2e9d65abSStephan Aßmus /*static*/ off_t 226*2e9d65abSStephan Aßmus AVFormatWriter::_Seek(void* cookie, off_t offset, int whence) 227*2e9d65abSStephan Aßmus { 228*2e9d65abSStephan Aßmus TRACE_IO("AVFormatWriter::_Seek(%p, %lld, %d)\n", 229*2e9d65abSStephan Aßmus cookie, offset, whence); 230*2e9d65abSStephan Aßmus 231*2e9d65abSStephan Aßmus AVFormatWriter* writer = reinterpret_cast<AVFormatWriter*>(cookie); 232*2e9d65abSStephan Aßmus 233*2e9d65abSStephan Aßmus BPositionIO* positionIO = dynamic_cast<BPositionIO*>(writer->fTarget); 234*2e9d65abSStephan Aßmus if (positionIO == NULL) 235*2e9d65abSStephan Aßmus return -1; 236*2e9d65abSStephan Aßmus 237*2e9d65abSStephan Aßmus // Support for special file size retrieval API without seeking 238*2e9d65abSStephan Aßmus // anywhere: 239*2e9d65abSStephan Aßmus if (whence == AVSEEK_SIZE) { 240*2e9d65abSStephan Aßmus off_t size; 241*2e9d65abSStephan Aßmus if (positionIO->GetSize(&size) == B_OK) 242*2e9d65abSStephan Aßmus return size; 243*2e9d65abSStephan Aßmus return -1; 244*2e9d65abSStephan Aßmus } 245*2e9d65abSStephan Aßmus 246*2e9d65abSStephan Aßmus off_t position = positionIO->Seek(offset, whence); 247*2e9d65abSStephan Aßmus TRACE_IO(" position: %lld\n", position); 248*2e9d65abSStephan Aßmus if (position < 0) 249*2e9d65abSStephan Aßmus return -1; 250*2e9d65abSStephan Aßmus 251*2e9d65abSStephan Aßmus return position; 252*2e9d65abSStephan Aßmus } 253*2e9d65abSStephan Aßmus 254*2e9d65abSStephan Aßmus 255