libeplayer3: cleanups

This commit is contained in:
martii
2014-04-07 23:00:03 +02:00
parent 5448fb35bf
commit fcd1dc8399
19 changed files with 1080 additions and 1212 deletions

View File

@@ -19,10 +19,6 @@
*
*/
/* ***************************** */
/* Includes */
/* ***************************** */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -64,51 +60,50 @@ bool WriterDIVX::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A
if (fd < 0 || !packet)
return false;
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers
unsigned int FakeHeaderLength;
unsigned char Version = 5;
unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */
BitPacker_t ld = { FakeHeaders, 0, 32 };
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers
unsigned int FakeHeaderLength;
unsigned char Version = 5;
unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE;
unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */
BitPacker_t ld = { FakeHeaders, 0, 32 };
usecPerFrame = 1000000 / av_q2d(stream->r_frame_rate);
usecPerFrame = 1000000 / av_q2d(stream->r_frame_rate);
memset(FakeHeaders, 0, sizeof(FakeHeaders));
memset(FakeHeaders, 0, sizeof(FakeHeaders));
/* Create info record for frame parser */
/* divx4 & 5
VOS
PutBits(&ld, 0x0, 8);
PutBits(&ld, 0x0, 8);
*/
PutBits(&ld, 0x1b0, 32); // startcode
PutBits(&ld, 0, 8); // profile = reserved
PutBits(&ld, 0x1b2, 32); // startcode (user data)
PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file
PutBits(&ld, usecPerFrame, 32);
// microseconds per frame
FlushBits(&ld);
/* Create info record for frame parser */
/* divx4 & 5
VOS
PutBits(&ld, 0x0, 8);
PutBits(&ld, 0x0, 8);
*/
PutBits(&ld, 0x1b0, 32); // startcode
PutBits(&ld, 0, 8); // profile = reserved
PutBits(&ld, 0x1b2, 32); // startcode (user data)
PutBits(&ld, 0x53545443, 32); // STTC - an embedded ST timecode from an avi file
PutBits(&ld, usecPerFrame, 32);
// microseconds per frame
FlushBits(&ld);
FakeHeaderLength = (ld.Ptr - (FakeHeaders));
FakeHeaderLength = (ld.Ptr - (FakeHeaders));
struct iovec iov[4];
int ic = 0;
iov[ic].iov_base = PesHeader;
iov[ic++].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode);
iov[ic].iov_base = FakeHeaders;
iov[ic++].iov_len = FakeHeaderLength;
struct iovec iov[4];
int ic = 0;
iov[ic].iov_base = PesHeader;
iov[ic++].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode);
iov[ic].iov_base = FakeHeaders;
iov[ic++].iov_len = FakeHeaderLength;
if (initialHeader) {
iov[ic].iov_base = stream->codec->extradata;
iov[ic++].iov_len = stream->codec->extradata_size;
if (initialHeader) {
iov[ic].iov_base = stream->codec->extradata;
iov[ic++].iov_len = stream->codec->extradata_size;
initialHeader = false;
}
iov[ic].iov_base = packet->data;
iov[ic++].iov_len = packet->size;
initialHeader = false;
}
iov[ic].iov_base = packet->data;
iov[ic++].iov_len = packet->size;
return writev(fd, iov, ic) > -1;
return writev(fd, iov, ic) > -1;
}
WriterDIVX::WriterDIVX()

View File

@@ -31,7 +31,7 @@
#include "writer.h"
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size.
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
class WriterDTS : public Writer
{
@@ -45,33 +45,33 @@ bool WriterDTS::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream
if (fd < 0 || !packet)
return false;
unsigned char PesHeader[PES_AUDIO_HEADER_SIZE];
unsigned char PesHeader[PES_AUDIO_HEADER_SIZE];
// #define DO_BYTESWAP
#ifdef DO_BYTESWAP
unsigned char Data[packet->size];
memcpy(Data, packet->data, packet->size);
unsigned char Data[packet->size];
memcpy(Data, packet->data, packet->size);
/* 16-bit byte swap all data before injecting it */
for (i = 0; i < packet->size; i += 2) {
unsigned char Tmp = Data[i];
Data[i] = Data[i + 1];
Data[i + 1] = Tmp;
}
/* 16-bit byte swap all data before injecting it */
for (i = 0; i < packet->size; i += 2) {
unsigned char Tmp = Data[i];
Data[i] = Data[i + 1];
Data[i + 1] = Tmp;
}
#endif
struct iovec iov[2];
struct iovec iov[2];
iov[0].iov_base = PesHeader;
iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE /*PRIVATE_STREAM_1_PES_START_CODE */ , pts, 0);
iov[0].iov_base = PesHeader;
iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE /*PRIVATE_STREAM_1_PES_START_CODE */ , pts, 0);
#ifdef DO_BYTESPWAP
iov[1].iov_base = Data;
iov[1].iov_base = Data;
#else
iov[1].iov_base = packet->data;
iov[1].iov_base = packet->data;
#endif
iov[1].iov_len = packet->size;
iov[1].iov_len = packet->size;
return writev(fd, iov, 2) > -1;
return writev(fd, iov, 2) > -1;
}
WriterDTS::WriterDTS()

View File

@@ -42,15 +42,15 @@ bool WriterFLAC::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* strea
if (fd < 0 || !packet)
return -1;
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
struct iovec iov[2];
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
struct iovec iov[2];
iov[0].iov_base = PesHeader;
iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0);
iov[1].iov_base = packet->data;
iov[1].iov_len = packet->size;
iov[0].iov_base = PesHeader;
iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0);
iov[1].iov_base = packet->data;
iov[1].iov_len = packet->size;
return writev(fd, iov, 2) > -1;
return writev(fd, iov, 2) > -1;
}
WriterFLAC::WriterFLAC()

View File

@@ -39,27 +39,27 @@ bool WriterH263::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* strea
{
if (fd < 0 || !packet)
return false;
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
int HeaderLength = InsertPesHeader(PesHeader, packet->size, H263_VIDEO_PES_START_CODE, pts, 0);
int HeaderLength = InsertPesHeader(PesHeader, packet->size, H263_VIDEO_PES_START_CODE, pts, 0);
int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size);
int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size);
int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
HeaderLength += PrivateHeaderLength;
HeaderLength += PrivateHeaderLength;
struct iovec iov[2];
iov[0].iov_base = PesHeader;
iov[0].iov_len = HeaderLength;
iov[1].iov_base = packet->data;
iov[1].iov_len = packet->size;
return writev(fd, iov, 2) > -1;
struct iovec iov[2];
iov[0].iov_base = PesHeader;
iov[0].iov_len = HeaderLength;
iov[1].iov_base = packet->data;
iov[1].iov_len = packet->size;
return writev(fd, iov, 2) > -1;
}
WriterH263::WriterH263()

View File

@@ -31,17 +31,17 @@
#include "pes.h"
#include "writer.h"
#define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24
#define CONTAINER_PARAMETERS_VERSION 0x00
#define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24
#define CONTAINER_PARAMETERS_VERSION 0x00
typedef struct avcC_s {
unsigned char Version; /* configurationVersion */
unsigned char Profile; /* AVCProfileIndication */
unsigned char Compatibility; /* profile_compatibility */
unsigned char Level; /* AVCLevelIndication */
unsigned char NalLengthMinusOne; /* held in bottom two bits */
unsigned char NumParamSets; /* held in bottom 5 bits */
unsigned char Params[1]; /* {length,params}{length,params}...sequence then picture */
unsigned char Version; // configurationVersion
unsigned char Profile; // AVCProfileIndication
unsigned char Compatibility; // profile_compatibility
unsigned char Level; // AVCLevelIndication
unsigned char NalLengthMinusOne; // held in bottom two bits
unsigned char NumParamSets; // held in bottom 5 bits
unsigned char Params[1]; // {length,params}{length,params}...sequence then picture
} avcC_t;
const unsigned char Head[] = { 0, 0, 0, 1 };
@@ -68,204 +68,200 @@ bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A
{
if (fd < 0 || !packet)
return false;
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
unsigned long long int VideoPts;
unsigned int TimeDelta;
unsigned int TimeScale;
int len = 0;
int ic = 0;
struct iovec iov[128];
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
unsigned long long int VideoPts;
unsigned int TimeDelta;
unsigned int TimeScale;
int len = 0;
int ic = 0;
struct iovec iov[128];
TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */
TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */
VideoPts = pts;
TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */
TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */
VideoPts = pts;
if ((packet->size > 3)
&& ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01)
|| (packet->data[0] == 0xff && packet->data[1] == 0xff && packet->data[2] == 0xff && packet->data[3] == 0xff))) {
unsigned int PacketLength = 0;
unsigned int FakeStartCode = /* (call->Version << 8) | */ PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader;
if (initialHeader) {
initialHeader = false;
iov[ic].iov_base = stream->codec->extradata;
iov[ic++].iov_len = stream->codec->extradata_size;
PacketLength += stream->codec->extradata_size;
}
iov[ic].iov_base = packet->data;
iov[ic++].iov_len = packet->size;
PacketLength += packet->size;
// Hellmaster1024:
// some packets will only be accepted by the player if we send one byte more than data is available.
// The content of this byte does not matter. It will be ignored by the player
iov[ic].iov_base = (void *) "";
iov[ic++].iov_len = 1;
iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode);
return writev(fd, iov, ic) > -1;
}
if ((packet->size > 3)
&& ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01)
|| (packet->data[0] == 0xff && packet->data[1] == 0xff && packet->data[2] == 0xff && packet->data[3] == 0xff))) {
unsigned int PacketLength = 0;
unsigned int FakeStartCode = /* (call->Version << 8) | */ PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader;
if (initialHeader) {
initialHeader = false;
iov[ic].iov_base = stream->codec->extradata;
iov[ic++].iov_len = stream->codec->extradata_size;
PacketLength += stream->codec->extradata_size;
}
iov[ic].iov_base = packet->data;
iov[ic++].iov_len = packet->size;
PacketLength += packet->size;
/*Hellmaster1024: some packets will only be accepted by the player if we send one byte more than
data is available. The content of this byte does not matter. It will be ignored
by the player */
iov[ic].iov_base = (void *) "";
iov[ic++].iov_len = 1;
iov[0].iov_len =
InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode);
return writev(fd, iov, ic) > -1;
}
avcC_t *avcCHeader = (avcC_t *) stream->codec->extradata;
unsigned int i;
unsigned int ParamSets;
unsigned int ParamOffset;
unsigned int InitialHeaderLength = 0;
unsigned int ParametersLength;
if (initialHeader) {
avcC_t *avcCHeader = (avcC_t *) stream->codec->extradata;
unsigned int i;
unsigned int ParamSets;
unsigned int ParamOffset;
unsigned int InitialHeaderLength = 0;
unsigned int ParametersLength;
if (avcCHeader == NULL) {
fprintf(stderr, "stream->codec->extradata == NULL\n");
return false;
}
if (avcCHeader == NULL) {
fprintf(stderr, "stream->codec->extradata == NULL\n");
return false;
if (avcCHeader->Version != 1)
fprintf(stderr, "Error unknown avcC version (%x). Expect problems.\n", avcCHeader->Version);
ParametersLength = 0;
unsigned char HeaderData[19];
HeaderData[ParametersLength++] = 0x00; // Start code
HeaderData[ParametersLength++] = 0x00;
HeaderData[ParametersLength++] = 0x01;
HeaderData[ParametersLength++] = NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS;
// Container message version - changes when/if we vary the format of the message
HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION;
HeaderData[ParametersLength++] = 0xff; // Field separator
if (TimeDelta == 0xffffffff)
TimeDelta = (TimeScale > 1000) ? 1001 : 1;
HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale
HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff;
HeaderData[ParametersLength++] = TimeScale & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period
HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff;
HeaderData[ParametersLength++] = TimeDelta & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits
assert(ParametersLength <= sizeof(HeaderData));
ic = 0;
iov[ic].iov_base = PesHeader;
iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
iov[ic].iov_base = HeaderData;
iov[ic++].iov_len = ParametersLength;
len = writev(fd, iov, ic);
if (len < 0)
return false;
NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1;
ParamSets = avcCHeader->NumParamSets & 0x1f;
ParamOffset = 0;
ic = 0;
iov[ic++].iov_base = PesHeader;
for (i = 0; i < ParamSets; i++) {
unsigned int PsLength =
(avcCHeader->Params[ParamOffset] << 8) +
avcCHeader->Params[ParamOffset + 1];
iov[ic].iov_base = (char *) Head;
iov[ic++].iov_len = sizeof(Head);
InitialHeaderLength += sizeof(Head);
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
iov[ic++].iov_len = PsLength;
InitialHeaderLength += PsLength;
ParamOffset += PsLength + 2;
}
ParamSets = avcCHeader->Params[ParamOffset];
ParamOffset++;
for (i = 0; i < ParamSets; i++) {
unsigned int PsLength =
(avcCHeader->Params[ParamOffset] << 8) +
avcCHeader->Params[ParamOffset + 1];
iov[ic].iov_base = (char *) Head;
iov[ic++].iov_len = sizeof(Head);
InitialHeaderLength += sizeof(Head);
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
iov[ic++].iov_len = PsLength;
InitialHeaderLength += PsLength;
ParamOffset += PsLength + 2;
}
iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
ssize_t l = writev(fd, iov, ic);
if (l < 0)
return false;
len += l;
initialHeader = 0;
}
if (avcCHeader->Version != 1)
fprintf(stderr, "Error unknown avcC version (%x). Expect problems.\n", avcCHeader->Version);
unsigned int SampleSize = packet->size;
unsigned int NalStart = 0;
unsigned int VideoPosition = 0;
ParametersLength = 0;
do {
unsigned int NalLength;
unsigned char NalData[4];
int NalPresent = 1;
unsigned char HeaderData[19];
HeaderData[ParametersLength++] = 0x00; // Start code
HeaderData[ParametersLength++] = 0x00;
HeaderData[ParametersLength++] = 0x01;
HeaderData[ParametersLength++] =
NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS;
// Container message version - changes when/if we vary the format of the message
HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION;
HeaderData[ParametersLength++] = 0xff; // Field separator
memcpy(NalData, packet->data + VideoPosition, NalLengthBytes);
VideoPosition += NalLengthBytes;
NalStart += NalLengthBytes;
switch (NalLengthBytes) {
case 1:
NalLength = (NalData[0]);
break;
case 2:
NalLength = (NalData[0] << 8) | (NalData[1]);
break;
case 3:
NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]);
break;
default:
NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]);
break;
}
if (TimeDelta == 0xffffffff)
TimeDelta = (TimeScale > 1000) ? 1001 : 1;
if (NalStart + NalLength > SampleSize) {
fprintf(stderr, "nal length past end of buffer - size %u frame offset %u left %u\n", NalLength, NalStart, SampleSize - NalStart);
NalStart = SampleSize;
} else {
NalStart += NalLength;
ic = 0;
iov[ic++].iov_base = PesHeader;
HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale
HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff;
HeaderData[ParametersLength++] = TimeScale & 0xff;
HeaderData[ParametersLength++] = 0xff;
if (NalPresent) {
NalPresent = 0;
iov[ic].iov_base = (char *) Head;
iov[ic++].iov_len = sizeof(Head);
}
HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period
HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = (TimeDelta >> 8) & 0xff;
HeaderData[ParametersLength++] = TimeDelta & 0xff;
HeaderData[ParametersLength++] = 0xff;
HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits
iov[ic].iov_base = packet->data + VideoPosition;
iov[ic++].iov_len = NalLength;
VideoPosition += NalLength;
assert(ParametersLength <= sizeof(HeaderData));
iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
ssize_t l = writev(fd, iov, ic);
if (l < 0)
return false;
len += l;
ic = 0;
iov[ic].iov_base = PesHeader;
iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
iov[ic].iov_base = HeaderData;
iov[ic++].iov_len = ParametersLength;
len = writev(fd, iov, ic);
if (len < 0)
return false;
VideoPts = INVALID_PTS_VALUE;
}
} while (NalStart < SampleSize);
NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1;
ParamSets = avcCHeader->NumParamSets & 0x1f;
ParamOffset = 0;
ic = 0;
iov[ic++].iov_base = PesHeader;
for (i = 0; i < ParamSets; i++) {
unsigned int PsLength =
(avcCHeader->Params[ParamOffset] << 8) +
avcCHeader->Params[ParamOffset + 1];
iov[ic].iov_base = (char *) Head;
iov[ic++].iov_len = sizeof(Head);
InitialHeaderLength += sizeof(Head);
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
iov[ic++].iov_len = PsLength;
InitialHeaderLength += PsLength;
ParamOffset += PsLength + 2;
}
ParamSets = avcCHeader->Params[ParamOffset];
ParamOffset++;
for (i = 0; i < ParamSets; i++) {
unsigned int PsLength =
(avcCHeader->Params[ParamOffset] << 8) +
avcCHeader->Params[ParamOffset + 1];
iov[ic].iov_base = (char *) Head;
iov[ic++].iov_len = sizeof(Head);
InitialHeaderLength += sizeof(Head);
iov[ic].iov_base = &avcCHeader->Params[ParamOffset + 2];
iov[ic++].iov_len = PsLength;
InitialHeaderLength += PsLength;
ParamOffset += PsLength + 2;
}
iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
ssize_t l = writev(fd, iov, ic);
if (l < 0)
return false;
len += l;
initialHeader = 0;
}
unsigned int SampleSize = packet->size;
unsigned int NalStart = 0;
unsigned int VideoPosition = 0;
do {
unsigned int NalLength;
unsigned char NalData[4];
int NalPresent = 1;
memcpy(NalData, packet->data + VideoPosition, NalLengthBytes);
VideoPosition += NalLengthBytes;
NalStart += NalLengthBytes;
switch (NalLengthBytes) {
case 1:
NalLength = (NalData[0]);
break;
case 2:
NalLength = (NalData[0] << 8) | (NalData[1]);
break;
case 3:
NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]);
break;
default:
NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]);
break;
}
if (NalStart + NalLength > SampleSize) {
fprintf(stderr, "nal length past end of buffer - size %u frame offset %u left %u\n", NalLength, NalStart, SampleSize - NalStart);
NalStart = SampleSize;
} else {
NalStart += NalLength;
ic = 0;
iov[ic++].iov_base = PesHeader;
if (NalPresent) {
NalPresent = 0;
iov[ic].iov_base = (char *) Head;
iov[ic++].iov_len = sizeof(Head);
}
iov[ic].iov_base = packet->data + VideoPosition;
iov[ic++].iov_len = NalLength;
VideoPosition += NalLength;
iov[0].iov_len =
InsertPesHeader(PesHeader, NalLength,
MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
ssize_t l = writev(fd, iov, ic);
if (l < 0)
return false;
len += l;
VideoPts = INVALID_PTS_VALUE;
}
} while (NalStart < SampleSize);
return len > -1;
return len > -1;
}
WriterH264::WriterH264()

View File

@@ -24,66 +24,65 @@
#include <sys/types.h>
#include <memory.h>
#include <asm/types.h>
#include <pthread.h>
#include <errno.h>
#include "misc.h"
void PutBits(BitPacker_t * ld, unsigned int code, unsigned int length)
{
unsigned int bit_buf;
unsigned int bit_left;
unsigned int bit_buf;
unsigned int bit_left;
bit_buf = ld->BitBuffer;
bit_left = ld->Remaining;
bit_buf = ld->BitBuffer;
bit_left = ld->Remaining;
#ifdef DEBUG_PUTBITS
if (ld->debug)
if (ld->debug)
dprintf("code = %d, length = %d, bit_buf = 0x%x, bit_left = %d\n",
code, length, bit_buf, bit_left);
#endif /* DEBUG_PUTBITS */
if (length < bit_left) {
/* fits into current buffer */
bit_buf = (bit_buf << length) | code;
bit_left -= length;
} else {
/* doesn't fit */
bit_buf <<= bit_left;
bit_buf |= code >> (length - bit_left);
ld->Ptr[0] = (char) (bit_buf >> 24);
ld->Ptr[1] = (char) (bit_buf >> 16);
ld->Ptr[2] = (char) (bit_buf >> 8);
ld->Ptr[3] = (char) bit_buf;
ld->Ptr += 4;
length -= bit_left;
bit_buf = code & ((1 << length) - 1);
bit_left = 32 - length;
bit_buf = code;
}
if (length < bit_left) {
/* fits into current buffer */
bit_buf = (bit_buf << length) | code;
bit_left -= length;
} else {
/* doesn't fit */
bit_buf <<= bit_left;
bit_buf |= code >> (length - bit_left);
ld->Ptr[0] = (char) (bit_buf >> 24);
ld->Ptr[1] = (char) (bit_buf >> 16);
ld->Ptr[2] = (char) (bit_buf >> 8);
ld->Ptr[3] = (char) bit_buf;
ld->Ptr += 4;
length -= bit_left;
bit_buf = code & ((1 << length) - 1);
bit_left = 32 - length;
bit_buf = code;
}
#ifdef DEBUG_PUTBITS
if (ld->debug)
dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf);
if (ld->debug)
dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf);
#endif /* DEBUG_PUTBITS */
/* writeback */
ld->BitBuffer = bit_buf;
ld->Remaining = bit_left;
/* writeback */
ld->BitBuffer = bit_buf;
ld->Remaining = bit_left;
}
void FlushBits(BitPacker_t * ld)
{
ld->BitBuffer <<= ld->Remaining;
while (ld->Remaining < 32) {
ld->BitBuffer <<= ld->Remaining;
while (ld->Remaining < 32) {
#ifdef DEBUG_PUTBITS
if (ld->debug)
dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24);
if (ld->debug)
dprintf("flushing 0x%2.2x\n", ld->BitBuffer >> 24);
#endif /* DEBUG_PUTBITS */
*ld->Ptr++ = ld->BitBuffer >> 24;
ld->BitBuffer <<= 8;
ld->Remaining += 8;
}
ld->Remaining = 32;
ld->BitBuffer = 0;
*ld->Ptr++ = ld->BitBuffer >> 24;
ld->BitBuffer <<= 8;
ld->Remaining += 8;
}
ld->Remaining = 32;
ld->BitBuffer = 0;
}

View File

@@ -42,15 +42,15 @@ bool WriterMP3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream
if (fd < 0 || !packet)
return false;
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
struct iovec iov[2];
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
struct iovec iov[2];
iov[0].iov_base = PesHeader;
iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0);
iov[1].iov_base = packet->data;
iov[1].iov_len = packet->size;
iov[0].iov_base = PesHeader;
iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0);
iov[1].iov_base = packet->data;
iov[1].iov_len = packet->size;
return writev(fd, iov, 2) > -1;
return writev(fd, iov, 2) > -1;
}
WriterMP3::WriterMP3()

View File

@@ -83,150 +83,149 @@ class WriterPCM : public Writer
bool WriterPCM::prepareClipPlay()
{
SubFrameLen = 0;
SubFramesPerPES = 0;
breakBufferFillSize = 0;
SubFrameLen = 0;
SubFramesPerPES = 0;
breakBufferFillSize = 0;
memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv));
memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv));
// figure out size of subframe and set up sample rate
switch (uSampleRate) {
case 48000:
SubFrameLen = 40;
break;
case 96000:
lpcm_prv[8] |= 0x10;
SubFrameLen = 80;
break;
case 192000:
lpcm_prv[8] |= 0x20;
SubFrameLen = 160;
break;
case 44100:
lpcm_prv[8] |= 0x80;
SubFrameLen = 40;
break;
case 88200:
lpcm_prv[8] |= 0x90;
SubFrameLen = 80;
break;
case 176400:
lpcm_prv[8] |= 0xA0;
SubFrameLen = 160;
break;
default:
break;
}
// figure out size of subframe and set up sample rate
switch (uSampleRate) {
case 48000:
SubFrameLen = 40;
break;
case 96000:
lpcm_prv[8] |= 0x10;
SubFrameLen = 80;
break;
case 192000:
lpcm_prv[8] |= 0x20;
SubFrameLen = 160;
break;
case 44100:
lpcm_prv[8] |= 0x80;
SubFrameLen = 40;
break;
case 88200:
lpcm_prv[8] |= 0x90;
SubFrameLen = 80;
break;
case 176400:
lpcm_prv[8] |= 0xA0;
SubFrameLen = 160;
break;
default:
break;
}
SubFrameLen *= uNoOfChannels;
SubFrameLen *= (uBitsPerSample / 8);
SubFrameLen *= uNoOfChannels;
SubFrameLen *= (uBitsPerSample / 8);
//rewrite PES size to have as many complete subframes per PES as we can
// FIXME: PES header size was hardcoded to 18 in earlier code. Actual size returned by InsertPesHeader is 14.
SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen;
SubFrameLen *= SubFramesPerPES;
//rewrite PES size to have as many complete subframes per PES as we can
// FIXME: PES header size was hardcoded to 18 in earlier code. Actual size returned by InsertPesHeader is 14.
SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen;
SubFrameLen *= SubFramesPerPES;
//set number of channels
lpcm_prv[10] = uNoOfChannels - 1;
//set number of channels
lpcm_prv[10] = uNoOfChannels - 1;
switch (uBitsPerSample) {
case 24:
lpcm_prv[7] |= 0x20;
case 16:
break;
default:
printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample);
return false;
}
switch (uBitsPerSample) {
case 24:
lpcm_prv[7] |= 0x20;
case 16:
break;
default:
printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample);
return false;
}
return true;
return true;
}
int WriterPCM::writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size)
{
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
if (initialHeader) {
initialHeader = false;
prepareClipPlay();
}
if (initialHeader) {
initialHeader = false;
prepareClipPlay();
}
unsigned int n;
unsigned char *injectBuffer = (unsigned char *) malloc(SubFrameLen);
unsigned int pos;
unsigned int n;
unsigned char *injectBuffer = (unsigned char *) malloc(SubFrameLen);
unsigned int pos;
for (pos = 0; pos < size;) {
for (pos = 0; pos < size;) {
//printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
if ((size - pos) < SubFrameLen) {
breakBufferFillSize = size - pos;
memcpy(breakBuffer, &data[pos],
sizeof(unsigned char) * breakBufferFillSize);
//printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
break;
}
//get first PES's worth
if (breakBufferFillSize > 0) {
memcpy(injectBuffer, breakBuffer, sizeof(unsigned char) * breakBufferFillSize);
memcpy(&injectBuffer[breakBufferFillSize], &data[pos], sizeof(unsigned char) * (SubFrameLen - breakBufferFillSize));
pos += (SubFrameLen - breakBufferFillSize);
breakBufferFillSize = 0;
} else {
memcpy(injectBuffer, &data[pos], sizeof(unsigned char) * SubFrameLen);
pos += SubFrameLen;
breakBufferFillSize = size - pos;
memcpy(breakBuffer, &data[pos], sizeof(unsigned char) * breakBufferFillSize);
//printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
break;
}
//get first PES's worth
if (breakBufferFillSize > 0) {
memcpy(injectBuffer, breakBuffer, sizeof(unsigned char) * breakBufferFillSize);
memcpy(&injectBuffer[breakBufferFillSize], &data[pos], sizeof(unsigned char) * (SubFrameLen - breakBufferFillSize));
pos += (SubFrameLen - breakBufferFillSize);
breakBufferFillSize = 0;
} else {
memcpy(injectBuffer, &data[pos], sizeof(unsigned char) * SubFrameLen);
pos += SubFrameLen;
}
struct iovec iov[3];
iov[0].iov_base = PesHeader;
iov[1].iov_base = lpcm_prv;
iov[1].iov_len = sizeof(lpcm_prv);
iov[2].iov_base = injectBuffer;
iov[2].iov_len = SubFrameLen;
//write the PCM data
if (uBitsPerSample == 16) {
for (n = 0; n < SubFrameLen; n += 2) {
unsigned char tmp;
tmp = injectBuffer[n];
injectBuffer[n] = injectBuffer[n + 1];
injectBuffer[n + 1] = tmp;
}
} else {
// 0 1 2 3 4 5 6 7 8 9 10 11
// A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a
// to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c
for (n = 0; n < SubFrameLen; n += 12) {
unsigned char t, *p = &injectBuffer[n];
t = p[0];
p[0] = p[2];
p[2] = p[5];
p[5] = p[7];
p[7] = p[11];
p[11] = p[9];
p[9] = p[3];
p[3] = p[4];
p[4] = p[8];
p[8] = t;
}
}
//increment err... subframe count?
lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F);
iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, Pts, 0);
int len = writev(fd, iov, 3);
if (len < 0)
break;
}
free(injectBuffer);
struct iovec iov[3];
iov[0].iov_base = PesHeader;
iov[1].iov_base = lpcm_prv;
iov[1].iov_len = sizeof(lpcm_prv);
iov[2].iov_base = injectBuffer;
iov[2].iov_len = SubFrameLen;
//write the PCM data
if (uBitsPerSample == 16) {
for (n = 0; n < SubFrameLen; n += 2) {
unsigned char tmp;
tmp = injectBuffer[n];
injectBuffer[n] = injectBuffer[n + 1];
injectBuffer[n + 1] = tmp;
}
} else {
// 0 1 2 3 4 5 6 7 8 9 10 11
// A1c A1b A1a-B1c B1b B1a-A2c A2b A2a-B2c B2b B2a
// to A1a A1b B1a B1b.A2a A2b B2a B2b-A1c B1c A2c B2c
for (n = 0; n < SubFrameLen; n += 12) {
unsigned char t, *p = &injectBuffer[n];
t = p[0];
p[0] = p[2];
p[2] = p[5];
p[5] = p[7];
p[7] = p[11];
p[11] = p[9];
p[9] = p[3];
p[3] = p[4];
p[4] = p[8];
p[8] = t;
}
}
//increment err... subframe count?
lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F);
iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, Pts, 0);
int len = writev(fd, iov, 3);
if (len < 0)
break;
}
free(injectBuffer);
return size;
return size;
}
void WriterPCM::Init()
{
initialHeader = true;
restart_audio_resampling = true;
initialHeader = true;
restart_audio_resampling = true;
}
extern int64_t calcPts(AVFormatContext *, AVStream *, int64_t);
@@ -237,7 +236,6 @@ bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
return false;
if (!packet) {
fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__);
restart_audio_resampling = true;
return true;
}
@@ -246,18 +244,13 @@ fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__);
unsigned int packet_size = packet->size;
if (restart_audio_resampling) {
fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__);
restart_audio_resampling = false;
initialHeader = true;
if (swr) {
if (swr)
swr_free(&swr);
swr = NULL; //FIXME: Needed?
}
if (decoded_frame) {
if (decoded_frame)
av_frame_free(&decoded_frame);
decoded_frame = NULL; //FIXME: Needed?
}
AVCodec *codec = avcodec_find_decoder(c->codec_id);
@@ -276,7 +269,6 @@ fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__);
int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, packet);
if (len < 0) {
fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__);
restart_audio_resampling = true;
break;
}
@@ -317,12 +309,10 @@ fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__);
e = swr_init(swr);
if (e < 0) {
fprintf(stderr,
"swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n",
fprintf(stderr, "swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n",
-e, (int) c->channel_layout,
(int) out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16);
swr_free(&swr);
swr = NULL;
}
}
@@ -365,7 +355,7 @@ WriterPCM::WriterPCM()
out_channel_layout = AV_CH_LAYOUT_STEREO;
restart_audio_resampling = true;
Register(this, AV_CODEC_ID_PCM_S16LE/*FIXME*/, AUDIO_ENCODING_LPCMA);
Register(this, AV_CODEC_ID_INJECTPCM, AUDIO_ENCODING_LPCMA);
}
static WriterPCM writer_pcm __attribute__ ((init_priority (300)));

View File

@@ -27,44 +27,11 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
#include <linux/dvb/stm_ioctls.h>
#include <memory.h>
#include <asm/types.h>
#include <pthread.h>
#include <errno.h>
#include "player.h"
#include "output.h"
#include "misc.h"
#include "pes.h"
#include "writer.h"
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
/* ***************************** */
/* Types */
/* ***************************** */
/* ***************************** */
/* Varaibles */
/* ***************************** */
/* ***************************** */
/* Prototypes */
/* ***************************** */
/* ***************************** */
/* Functions */
/* ***************************** */
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size)
{

View File

@@ -65,7 +65,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
if (fd < 0 || !packet)
return false;
if (initialHeader) {
if (initialHeader) {
initialHeader = false;
FrameHeaderSeen = false;
@@ -74,15 +74,15 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
const unsigned char Metadata[] = {
0x00, 0x00, 0x00, 0xc5,
0x04, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */
0x00, 0x00, 0x00, 0x00, /* Struct A */
0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, /* Struct B */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0xc5,
0x04, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */
0x00, 0x00, 0x00, 0x00, /* Struct A */
0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, /* Struct B */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
@@ -158,7 +158,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
HeaderLength += sizeof(Vc1FrameStartCode);
}
insertSampleHeader = 0;
insertSampleHeader = 0;
}
struct iovec iov[2];

View File

@@ -33,22 +33,22 @@
#include <algorithm>
#define WMV3_PRIVATE_DATA_LENGTH 4
#define WMV3_PRIVATE_DATA_LENGTH 4
static const unsigned char Metadata[] = {
0x00, 0x00, 0x00, 0xc5,
0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc5,
0x04, 0x00, 0x00, 0x00,
#define METADATA_STRUCT_C_START 8
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */
0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */
#define METADATA_STRUCT_A_START 12
0x00, 0x00, 0x00, 0x00, /* Struct A */
0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, /* Struct A */
0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00,
#define METADATA_STRUCT_B_START 24
0x60, 0x00, 0x00, 0x00, /* Struct B */
0x00, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, /* Struct B */
0x00, 0x00, 0x00, 0x00,
#define METADATA_STRUCT_B_FRAMERATE_START 32
0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00
};
class WriterWMV : public Writer
@@ -63,7 +63,7 @@ class WriterWMV : public Writer
void WriterWMV::Init()
{
initialHeader = 1;
initialHeader = 1;
}
bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts)
@@ -71,92 +71,92 @@ bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV
if (fd < 0 || !packet)
return false;
if (initialHeader) {
if (initialHeader) {
#define PES_MIN_HEADER_SIZE 9
unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128];
unsigned char *PesPtr;
unsigned int MetadataLength;
unsigned int usecPerFrame = ((10000000.0 / av_q2d(stream->r_frame_rate)));
unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128];
unsigned char *PesPtr;
unsigned int MetadataLength;
unsigned int usecPerFrame = ((10000000.0 / av_q2d(stream->r_frame_rate)));
PesPtr = &PesPacket[PES_MIN_HEADER_SIZE];
PesPtr = &PesPacket[PES_MIN_HEADER_SIZE];
memcpy(PesPtr, Metadata, sizeof(Metadata));
PesPtr += METADATA_STRUCT_C_START;
memcpy(PesPtr, Metadata, sizeof(Metadata));
PesPtr += METADATA_STRUCT_C_START;
unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH] = { 0 };
memcpy(privateData, stream->codec->extradata, stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : stream->codec->extradata_size);
unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH] = { 0 };
memcpy(privateData, stream->codec->extradata, stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : stream->codec->extradata_size);
memcpy(PesPtr, privateData, WMV3_PRIVATE_DATA_LENGTH);
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
memcpy(PesPtr, privateData, WMV3_PRIVATE_DATA_LENGTH);
PesPtr += WMV3_PRIVATE_DATA_LENGTH;
/* Metadata Header Struct A */
*PesPtr++ = (stream->codec->height >> 0) & 0xff;
*PesPtr++ = (stream->codec->height >> 8) & 0xff;
*PesPtr++ = (stream->codec->height >> 16) & 0xff;
*PesPtr++ = stream->codec->height >> 24;
*PesPtr++ = (stream->codec->width >> 0) & 0xff;
*PesPtr++ = (stream->codec->width >> 8) & 0xff;
*PesPtr++ = (stream->codec->width >> 16) & 0xff;
*PesPtr++ = stream->codec->width >> 24;
/* Metadata Header Struct A */
*PesPtr++ = (stream->codec->height >> 0) & 0xff;
*PesPtr++ = (stream->codec->height >> 8) & 0xff;
*PesPtr++ = (stream->codec->height >> 16) & 0xff;
*PesPtr++ = stream->codec->height >> 24;
*PesPtr++ = (stream->codec->width >> 0) & 0xff;
*PesPtr++ = (stream->codec->width >> 8) & 0xff;
*PesPtr++ = (stream->codec->width >> 16) & 0xff;
*PesPtr++ = stream->codec->width >> 24;
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */
*PesPtr++ = (usecPerFrame >> 0) & 0xff;
*PesPtr++ = (usecPerFrame >> 8) & 0xff;
*PesPtr++ = (usecPerFrame >> 16) & 0xff;
*PesPtr++ = usecPerFrame >> 24;
*PesPtr++ = (usecPerFrame >> 0) & 0xff;
*PesPtr++ = (usecPerFrame >> 8) & 0xff;
*PesPtr++ = (usecPerFrame >> 16) & 0xff;
*PesPtr++ = usecPerFrame >> 24;
MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE];
MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE];
int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
if (write(fd, PesPacket, HeaderLength + MetadataLength) < 0)
return false;
if (write(fd, PesPacket, HeaderLength + MetadataLength) < 0)
return false;
initialHeader = false;
}
if (packet->size > 0 && packet->data) {
int Position = 0;
bool insertSampleHeader = true;
uint64_t _pts = pts;
while (Position < packet->size) {
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 };
int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0);
if (insertSampleHeader) {
unsigned int PesLength;
unsigned int PrivateHeaderLength;
PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size);
/* Update PesLength */
PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
HeaderLength += PrivateHeaderLength;
insertSampleHeader = false;
}
uint8_t PacketStart[packet->size + HeaderLength];
memcpy(PacketStart, PesHeader, HeaderLength);
memcpy(PacketStart + HeaderLength, packet->data + Position, PacketLength);
if (write(fd, PacketStart, PacketLength + HeaderLength) < 0)
return false;
Position += PacketLength;
_pts = INVALID_PTS_VALUE;
initialHeader = false;
}
}
return true;
if (packet->size > 0 && packet->data) {
int Position = 0;
bool insertSampleHeader = true;
uint64_t _pts = pts;
while (Position < packet->size) {
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 };
int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0);
if (insertSampleHeader) {
unsigned int PesLength;
unsigned int PrivateHeaderLength;
PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size);
/* Update PesLength */
PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength;
PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff;
PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff;
PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength;
PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT;
HeaderLength += PrivateHeaderLength;
insertSampleHeader = false;
}
uint8_t PacketStart[packet->size + HeaderLength];
memcpy(PacketStart, PesHeader, HeaderLength);
memcpy(PacketStart + HeaderLength, packet->data + Position, PacketLength);
if (write(fd, PacketStart, PacketLength + HeaderLength) < 0)
return false;
Position += PacketLength;
_pts = INVALID_PTS_VALUE;
}
}
return true;
}
WriterWMV::WriterWMV()