Example #1
0
bool WriterAC3::Write(AVPacket *packet, int64_t pts)
{
	if (!packet || !packet->data)
		return false;

	uint8_t PesHeader[PES_MAX_HEADER_SIZE];

	for (int pos = 0; pos < packet->size; )
	{
		int PacketLength = std::min(packet->size - pos, MAX_PES_PACKET_SIZE);
		struct iovec iov[2];
		iov[0].iov_base = PesHeader;
		iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, PRIVATE_STREAM_1_PES_START_CODE, pts, 0);
		iov[1].iov_base = packet->data + pos;
		iov[1].iov_len = PacketLength;

		ssize_t l = writev(fd, iov, 2);
		if (l < 0)
		{
			return false;
		}
		pos += PacketLength;
		pts = INVALID_PTS_VALUE;
	}
	return true;
}
Example #2
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    unsigned char               PesHeader[PES_MAX_HEADER_SIZE];
    int len = 0;
    unsigned int Position = 0;

    mpeg2_printf(10, "\n");

    if (call == NULL)
    {
        mpeg2_err("call data is NULL...\n");
        return 0;
    }

    mpeg2_printf(10, "VideoPts %lld\n", call->Pts);

    if ((call->data == NULL) || (call->len <= 0))
    {
        mpeg2_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        mpeg2_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    while(Position < call->len) 
    {
        int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
                           (call->len - Position) : MAX_PES_PACKET_SIZE;

        int Remaining = call->len - Position - PacketLength;

        mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);

        struct iovec iov[2];
        iov[0].iov_base = PesHeader;
        iov[0].iov_len = InsertPesHeader (PesHeader, PacketLength, 0xe0, call->Pts, 0);
        iov[1].iov_base = call->data + Position;
        iov[1].iov_len = PacketLength;

        ssize_t l = writev_with_retry(call->fd, iov, 2);
        if (l < 0) {
            len = l;
            break;
        }
        len += l;

        Position += PacketLength;
        call->Pts = INVALID_PTS_VALUE;
    }

    mpeg2_printf(10, "< len %d\n", len);
    return len;
}
Example #3
0
static int writeData(void* _call)
{
	WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

	int             i = 0;
	unsigned char   PesHeader[PES_AUDIO_HEADER_SIZE];
	unsigned char * Data = 0;

	dts_printf(10, "\n");

	if (call == NULL)
	{
		dts_err("call data is NULL...\n");
		return 0;
	}

	dts_printf(10, "AudioPts %lld\n", call->Pts);

	if ((call->data == NULL) || (call->len <= 0))
	{
		dts_err("parsing NULL Data. ignoring...\n");
		return 0;
	}

	if (call->fd < 0)
	{
		dts_err("file pointer < 0. ignoring ...\n");
		return 0;
	}

	memset (PesHeader, '0', PES_AUDIO_HEADER_SIZE);

	Data = (unsigned char *) malloc(call->len);
	memcpy(Data, call->data, call->len);

	/* 16-bit byte swap all data before injecting it */
	for (i=0; i< call->len; i+=2)
	{
		unsigned char Tmp = Data[i];
		Data[i] = Data[i+1];
		Data[i+1] = Tmp;
	}

	int HeaderLength    = InsertPesHeader (PesHeader, call->len, MPEG_AUDIO_PES_START_CODE/*PRIVATE_STREAM_1_PES_START_CODE*/, call->Pts, 0);
	unsigned char* PacketStart = malloc(call->len + HeaderLength);
	memcpy (PacketStart, PesHeader, HeaderLength);
	memcpy (PacketStart + HeaderLength, call->data, call->len);

	int len = write(call->fd,PacketStart,call->len + HeaderLength);

	free(PacketStart);
	free(Data);

	dts_printf(10, "< len %d\n", len);
	return len;
}
Example #4
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

    mpeg4_printf(10, "\n");

    if (call == NULL)
    {
        mpeg4_err("call data is NULL...\n");
        return 0;
    }

    if ((call->data == NULL) || (call->len <= 0))
    {
        mpeg4_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        mpeg4_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    mpeg4_printf(10, "VideoPts %lld\n", call->Pts);


    unsigned int PacketLength = call->len;
    if (initialHeader && call->private_size && call->private_data != NULL)
    {
        PacketLength += call->private_size;
    }

    struct iovec iov[3];
    int ic = 0;
    iov[ic].iov_base = PesHeader;
    iov[ic++].iov_len = InsertPesHeader (PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);

    if (initialHeader && call->private_size && call->private_data != NULL)
    {
        initialHeader = 0;
        iov[ic].iov_base = call->private_data;
        iov[ic++].iov_len = call->private_size;
    }
    iov[ic].iov_base = call->data;
    iov[ic++].iov_len = call->len;

    int len = call->WriteV(call->fd, iov, ic);

    mpeg4_printf(10, "xvid_Write < len=%d\n", len);

    return len;
}
Example #5
0
static int writeData(void* _call, int is_vp6)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;
    vp_printf(10, "\n");

    if (call == NULL) 
    {
        vp_err("call data is NULL...\n");
        return 0;
    }

    if ((call->data == NULL) || (call->len <= 0)) 
    {
        vp_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0) 
    {
        vp_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    vp_printf(10, "VideoPts %lld\n", call->Pts);
    vp_printf(10, "Got Private Size %d\n", call->private_size);
    
    unsigned char PesHeader[PES_MAX_HEADER_SIZE];
    struct iovec iov[2];
    
    iov[0].iov_base = PesHeader;
    uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);
    uint32_t len = call->len + 4 + 6;
    memcpy(PesHeader + pes_header_len, "BCMV", 4);
    pes_header_len += 4;
    if (is_vp6)
            ++len;
    PesHeader[pes_header_len++] = (len & 0xFF000000) >> 24;
    PesHeader[pes_header_len++] = (len & 0x00FF0000) >> 16;
    PesHeader[pes_header_len++] = (len & 0x0000FF00) >> 8;
    PesHeader[pes_header_len++] = (len & 0x000000FF) >> 0;
    PesHeader[pes_header_len++] = 0;
    PesHeader[pes_header_len++] = 0;
    if (is_vp6)
            PesHeader[pes_header_len++] = 0;
    iov[0].iov_len = pes_header_len;
    iov[1].iov_base = call->data;
    iov[1].iov_len = call->len;
    
    return writev_with_retry(call->fd, iov, 2);
}
Example #6
0
File: mp3.c Project: Audioniek/apps
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    unsigned char  PesHeader[PES_MAX_HEADER_SIZE + 22];

    mp3_printf(10, "\n");

    if (call == NULL)
    {
        mp3_err("call data is NULL...\n");
        return 0;
    }

    mp3_printf(10, "AudioPts %lld\n", call->Pts);

    if ((call->data == NULL) || (call->len <= 0))
    {
        mp3_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        mp3_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    call->private_size = 0;
    
    uint32_t headerSize = InsertPesHeader (PesHeader, call->len + call->private_size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
    if(call->private_size > 0)
    {
        memcpy(&PesHeader[headerSize], call->private_data, call->private_size);
        headerSize += call->private_size;
    }
    struct iovec iov[2];
    iov[0].iov_base = PesHeader;
    iov[0].iov_len = headerSize;
    iov[1].iov_base = call->data;
    iov[1].iov_len = call->len;

    int len = call->WriteV(call->fd, iov, 2);

    mp3_printf(10, "mp3_Write-< len=%d\n", len);
    return len;
}
Example #7
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    ac3_printf(10, "\n");

    unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

    if (call == NULL)
    {
        ac3_err("call data is NULL...\n");
        return 0;
    }

    ac3_printf(10, "AudioPts %lld\n", call->Pts);

    if ((call->data == NULL) || (call->len <= 0))
    {
        ac3_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        ac3_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    struct iovec iov[3];

    iov[0].iov_base = PesHeader;
    iov[0].iov_len = InsertPesHeader (PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); //+ sizeof(AC3_SYNC_HEADER)
    
    //PesHeader[6] = 0x81;
    //PesHeader[7] = 0x80;
    //PesHeader[8] = 0x09;
                
    //iov[1].iov_base = AC3_SYNC_HEADER;
    //iov[1].iov_len = sizeof(AC3_SYNC_HEADER);
    iov[1].iov_base = call->data;
    iov[1].iov_len = call->len;
    
    ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len);

    return writev_with_retry(call->fd, iov, 2);
}
Example #8
0
static int writeData(void* _call)
{
	WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

	unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

	flac_printf(10, "\n");

	if (call == NULL)
	{
		flac_err("call data is NULL...\n");
		return 0;
	}

	flac_printf(10, "AudioPts %lld\n", call->Pts);

	if ((call->data == NULL) || (call->len <= 0))
	{
		flac_err("parsing NULL Data. ignoring...\n");
		return 0;
	}

	if (call->fd < 0)
	{
		flac_err("file pointer < 0. ignoring ...\n");
		return 0;
	}

	int HeaderLength = InsertPesHeader (PesHeader, call->len , MPEG_AUDIO_PES_START_CODE, call->Pts, 0);

	unsigned char* PacketStart = malloc(call->len + HeaderLength);

	memcpy (PacketStart, PesHeader, HeaderLength);
	memcpy (PacketStart + HeaderLength, call->data, call->len);

	int len = write(call->fd, PacketStart, call->len + HeaderLength);

	free(PacketStart);

	flac_printf(10, "flac_Write-< len=%d\n", len);
	return len;
}
Example #9
0
static int writeData(void *_call)
{
	WriterAVCallData_t *call = (WriterAVCallData_t *) _call;

	unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

	flac_printf(10, "\n");

	if (call == NULL)
	{
		flac_err("call data is NULL...\n");
		return 0;
	}

	flac_printf(10, "AudioPts %lld\n", call->Pts);

	if ((call->data == NULL) || (call->len <= 0))
	{
		flac_err("parsing NULL Data. ignoring...\n");
		return 0;
	}

	if (call->fd < 0)
	{
		flac_err("file pointer < 0. ignoring ...\n");
		return 0;
	}

	struct iovec iov[2];
	iov[0].iov_base = PesHeader;
	iov[0].iov_len = InsertPesHeader(PesHeader, call->len , MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
	iov[1].iov_base = call->data;
	iov[1].iov_len = call->len;

	int len = writev(call->fd, iov, 2);

	flac_printf(10, "flac_Write-< len=%d\n", len);
	return len;
}
Example #10
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    int len = 0;
    vc1_printf(10, "\n");

    if (call == NULL) 
    {
        vc1_err("call data is NULL...\n");
        return 0;
    }

    if ((call->data == NULL) || (call->len <= 0))
    {
        vc1_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        vc1_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    vc1_printf(10, "VideoPts %lld\n", call->Pts);
    vc1_printf(10, "Got Private Size %d\n", call->private_size);

    if (initialHeader)
    {
        unsigned char   PesHeader[PES_MAX_HEADER_SIZE];
        unsigned char   PesPayload[128];
        unsigned char  *PesPtr;
        unsigned int    crazyFramerate = 0;
        struct iovec    iov[2];

        vc1_printf(10, "Framerate: %u\n", call->FrameRate);
        vc1_printf(10, "biWidth: %d\n",   call->Width);
        vc1_printf(10, "biHeight: %d\n",  call->Height);
        
        crazyFramerate = ((10000000.0 / call->FrameRate) * 1000.0);
        vc1_printf(10, "crazyFramerate: %u\n", crazyFramerate);
        
        memset(PesPayload, 0, sizeof(PesPayload));
        
        PesPtr = PesPayload;
        
        memcpy(PesPtr, SequenceLayerStartCode, sizeof(SequenceLayerStartCode));
        PesPtr += sizeof(SequenceLayerStartCode);

        memcpy(PesPtr, Metadata, sizeof(Metadata));
        PesPtr += METADATA_STRUCT_C_START;
        PesPtr += WMV3_PRIVATE_DATA_LENGTH;

        /* Metadata Header Struct A */
        *PesPtr++ = (call->Height >>  0) & 0xff;
        *PesPtr++ = (call->Height >>  8) & 0xff;
        *PesPtr++ = (call->Height >> 16) & 0xff;
        *PesPtr++ =  call->Height >> 24;
        *PesPtr++ = (call->Width  >>  0) & 0xff;
        *PesPtr++ = (call->Width  >>  8) & 0xff;
        *PesPtr++ = (call->Width  >> 16) & 0xff;
        *PesPtr++ =  call->Width  >> 24;

        PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */

        *PesPtr++ = (crazyFramerate >>  0) & 0xff;
        *PesPtr++ = (crazyFramerate >>  8) & 0xff;
        *PesPtr++ = (crazyFramerate >> 16) & 0xff;
        *PesPtr++ =  crazyFramerate >> 24;

        iov[0].iov_base = PesHeader;
        iov[1].iov_base = PesPayload;
        iov[1].iov_len = PesPtr - PesPayload;
        iov[0].iov_len = InsertPesHeader (PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
        len = call->WriteV(call->fd, iov, 2);

        /* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */
        iov[0].iov_base = PesHeader;
        iov[1].iov_base = call->private_data;
        iov[1].iov_len = call->private_size;
        iov[0].iov_len = InsertPesHeader (PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
        len = call->WriteV(call->fd, iov, 2);

        initialHeader = 0;
    }

    if(call->len > 0 && call->data) 
    {
        uint32_t Position = 0;
        uint8_t insertSampleHeader = 1;

        while(Position < call->len) 
        {

            int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ?
                       (call->len - Position) : MAX_PES_PACKET_SIZE;

            int32_t Remaining = call->len - Position - PacketLength;

            vc1_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position);

            uint8_t PesHeader[PES_MAX_HEADER_SIZE];
            int32_t HeaderLength = InsertPesHeader (PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0);

            if(insertSampleHeader) 
            {
                const uint8_t Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE};

                if (!FrameHeaderSeen && (call->len > 3) && (memcmp (call->data, Vc1FrameStartCode, 4) == 0))
                {
                    FrameHeaderSeen = 1;
                }
                
                if (!FrameHeaderSeen)
                {
                    memcpy (&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
                    HeaderLength += sizeof(Vc1FrameStartCode);
                }
                insertSampleHeader = 0;
            }

            struct iovec iov[2];
            iov[0].iov_base = PesHeader;
            iov[0].iov_len = HeaderLength;
            iov[1].iov_base = call->data + Position;
            iov[1].iov_len = PacketLength;

            ssize_t l = call->WriteV(call->fd, iov, 2);
            if (l < 0) 
            {
                len = l;
                break;
            }
            len += l;

            Position += PacketLength;
            call->Pts = INVALID_PTS_VALUE;
        }
    }

    vc1_printf(10, "< %d\n", len);
    return len;
}
Example #11
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    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[IOVEC_SIZE];
    h265_printf(20, "\n");

    if (call == NULL)
    {
        h264_err("call data is NULL...\n");
        return 0;
    }

    TimeDelta = call->FrameRate;
    TimeScale = call->FrameScale;
    VideoPts  = call->Pts;
    
    h265_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale);

    if ((call->data == NULL) || (call->len <= 0))
    {
        h264_err("NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        h264_err("file pointer < 0. ignoring ...\n");
        return 0;
    }
    
    if( call->InfoFlags & 0x1 ) // TS container
    {
        h265_printf(10, "H265 simple inject method!\n");
        uint32_t PacketLength = 0;
        uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE;
        
        iov[ic++].iov_base = PesHeader;
        initialHeader = 0;
        if (initialHeader) 
        {
            initialHeader = 0;
            iov[ic].iov_base  = call->private_data;
            iov[ic++].iov_len = call->private_size;
            PacketLength     += call->private_size;
        }

        iov[ic].iov_base = "";
        iov[ic++].iov_len = 1;
        
        iov[ic].iov_base  = call->data;
        iov[ic++].iov_len = call->len;
        PacketLength     += call->len;
        
        iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode);
        
        return call->WriteV(call->fd, iov, ic);
    }

    uint32_t PacketLength = 0;
    
    ic = 0;
    iov[ic++].iov_base = PesHeader;
    
    if (initialHeader)
    {
        if (CodecData)
        {
            free(CodecData);
            CodecData = NULL;
        }
        
        uint8_t  *private_data = call->private_data;
        uint32_t  private_size = call->private_size;
    
        PreparCodecData(private_data, private_size, &NalLengthBytes);
        
        if (CodecData != NULL)
        {
            iov[ic].iov_base  = CodecData;
            iov[ic++].iov_len = CodecDataLen;
            PacketLength     += CodecDataLen;
            initialHeader = 0;
        }
    }

    if (CodecData != NULL)
    {
        uint32_t pos = 0;
        do
        {
            if (ic >= IOVEC_SIZE)
            {
                h264_err(">> Drop data due to ic overflow\n");
                break;
            }
            
            uint32_t pack_len = 0;
            uint32_t i = 0;
            for (i = 0; i < NalLengthBytes; i++, pos++)
            {
                pack_len <<= 8;
                pack_len += call->data[pos];
            }
            
            if ( (pos + pack_len) > call->len )
            {
                pack_len = call->len - pos;
            }
            
            iov[ic].iov_base  = Head;
            iov[ic++].iov_len = sizeof(Head);
            PacketLength += sizeof(Head);
            
            iov[ic].iov_base  = call->data + pos;
            iov[ic++].iov_len = pack_len;
            PacketLength     += pack_len;
    
            pos += pack_len;
            
        } while ((pos + NalLengthBytes) < call->len);
        
        h265_printf (10, "<<<< PacketLength [%d]\n", PacketLength);
        iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0);
        
        len = call->WriteV(call->fd, iov, ic);
        PacketLength += iov[0].iov_len;
        if (PacketLength != len)
        {
            h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength);
        }
    }

    h265_printf (10, "< len %d\n", len);
    return len;
}
Example #12
0
static int writeData(void* _call)
{
	WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

	int len = 0;

	wma_printf(10, "\n");

	if (call == NULL)
	{
		wma_err("call data is NULL...\n");
		return 0;
	}

	wma_printf(10, "AudioPts %lld\n", call->Pts);

	if ((call->data == NULL) || (call->len <= 0))
	{
		wma_err("parsing NULL Data. ignoring...\n");
		return 0;
	}

	if (call->fd < 0)
	{
		wma_err("file pointer < 0. ignoring ...\n");
		return 0;
	}

	if (initialHeader) 
	{

		unsigned char  PesHeader[PES_MAX_HEADER_SIZE];
		int HeaderLength;

		if ((call->private_size <= 0) || (call->private_data == NULL))
		{
			wma_err("private NULL.\n");
			return -1;
		}

		HeaderLength = InsertPesHeader (PesHeader, call->private_size, MPEG_AUDIO_PES_START_CODE, 0, 0);

		unsigned char* PacketStart = malloc(call->private_size + HeaderLength);
		memcpy (PacketStart, PesHeader, HeaderLength);
		memcpy (PacketStart + HeaderLength, call->private_data, call->private_size);

		len = write(call->fd, PacketStart, call->private_size + HeaderLength);

		free(PacketStart);

		initialHeader = 0;
	}

	if (call->len > 0 && call->data)
	{
		unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

		int HeaderLength = InsertPesHeader (PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);

		unsigned char* PacketStart = malloc(call->len + HeaderLength);
		memcpy (PacketStart, PesHeader, HeaderLength);
		memcpy (PacketStart + HeaderLength, call->data, call->len);

		len = write(call->fd, PacketStart, call->len + HeaderLength);

		free(PacketStart);
	}

	wma_printf(10, "wma < %d\n", len);

	return len;
}
Example #13
0
static int writeData(void* _call)
{
	WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

	unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

	pcm_printf(10, "\n");

	if (!call) {
		pcm_err("call data is NULL...\n");
		return 0;
	}

	pcm_printf(10, "AudioPts %lld\n", call->Pts);

	if (!call->data || (call->len <= 0)) {
		pcm_err("parsing NULL Data. ignoring...\n");
		return 0;
	}

	if (call->fd < 0) {
		pcm_err("file pointer < 0. ignoring ...\n");
		return 0;
	}

	pcmPrivateData_t*         pcmPrivateData          = (pcmPrivateData_t*)call->private_data;

	if (initialHeader) {
		initialHeader = 0;
		prepareClipPlay(pcmPrivateData->uNoOfChannels, pcmPrivateData->uSampleRate, 
				pcmPrivateData->uBitsPerSample, pcmPrivateData->bLittleEndian);
	}

	unsigned char * buffer = call->data;
	unsigned int size = call->len;

	unsigned int n;
	unsigned char * injectBuffer = (unsigned char *)malloc(SubFrameLen);
	unsigned int pos;

	for(pos = 0; pos < size; )
	{
		//printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
		if((size - pos) < SubFrameLen)
		{
			breakBufferFillSize = size - pos;
			memcpy(breakBuffer, &buffer[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], &buffer[pos], sizeof(unsigned char)*(SubFrameLen - breakBufferFillSize));
			pos += (SubFrameLen - breakBufferFillSize);
			breakBufferFillSize = 0;
		} else
		{
		        memcpy(injectBuffer, &buffer[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(pcmPrivateData->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, call->Pts, 0);
		int len = writev(call->fd, iov, 3);
		if (len < 0)
			break;
	}
	free(injectBuffer);

	return size;
}
Example #14
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    int len = 0;

    vc1_printf(10, "\n");

    if (call == NULL) 
    {
        vc1_err("call data is NULL...\n");
        return 0;
    }

    if ((call->data == NULL) || (call->len <= 0)) 
    {
        vc1_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0) 
    {
        vc1_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    vc1_printf(10, "VideoPts %lld\n", call->Pts);
    vc1_printf(10, "Got Private Size %d\n", call->private_size);
    
    unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)];
    int32_t ic = 0;
    struct iovec iov[5];
    unsigned int PacketLength = 0;
    
    iov[ic++].iov_base = PesHeader;
    if (initialHeader) 
    {
        initialHeader = 0;
        if(videocodecdata.data)
        {
            free(videocodecdata.data);
            videocodecdata.data = NULL;
        }
        videocodecdata.length = call->private_size + 8;
        videocodecdata.data  = malloc(videocodecdata.length);
        memset(videocodecdata.data, 0, videocodecdata.length);
        memcpy(videocodecdata.data + 8, call->private_data, call->private_size);
        if(IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata))
        {
            iov[ic].iov_base  = videocodecdata.data;
            iov[ic++].iov_len = videocodecdata.length;
            PacketLength     += videocodecdata.length;
        }
    }
    
    uint8_t needFrameStartCode = 0;
    if( sizeof(Vc1FrameStartCode) >= call->len
        || memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0 )
    {
        needFrameStartCode = 1;
        PacketLength += sizeof(Vc1FrameStartCode);
    }
    
    iov[ic].iov_base  = call->data;
    iov[ic++].iov_len = call->len;
    PacketLength     += call->len;
    
    iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);

    /* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */
    PesHeader[6] |= 1;
    
    if(needFrameStartCode)
    {
        memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode) );
        iov[0].iov_len += sizeof(Vc1FrameStartCode);
    }
    
    if(videocodecdata.data)
    {
        free(videocodecdata.data);
        videocodecdata.data = NULL;
    }
    
    return call->WriteV(call->fd, iov, ic);
}
Example #15
0
File: pcm.c Project: Audioniek/apps
static int32_t writeData(void *_call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

    pcm_printf(10, "\n");

    if (!call)
    {
        pcm_err("call data is NULL...\n");
        return 0;
    }

    pcm_printf(10, "AudioPts %lld\n", call->Pts);

    if (!call->data || (call->len <= 0))
    {
        pcm_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        pcm_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t*)call->private_data;

    if (initialHeader)
    {
        uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id;
        uint8_t LE = 0;
        switch (codecID)
        {
            case AV_CODEC_ID_PCM_S8:
            case AV_CODEC_ID_PCM_U8:
                break;
            case AV_CODEC_ID_PCM_S16LE:
            case AV_CODEC_ID_PCM_U16LE:
                LE = 1;
            case AV_CODEC_ID_PCM_S16BE:
            case AV_CODEC_ID_PCM_U16BE:
                break;
            case AV_CODEC_ID_PCM_S24LE:
            case AV_CODEC_ID_PCM_U24LE:
                LE = 1;
            case AV_CODEC_ID_PCM_S24BE:
            case AV_CODEC_ID_PCM_U24BE:
                break;
            case AV_CODEC_ID_PCM_S32LE:
            case AV_CODEC_ID_PCM_U32LE:
                LE = 1;
            case AV_CODEC_ID_PCM_S32BE:
            case AV_CODEC_ID_PCM_U32BE:
                break;
            default:
                break;
        }
        initialHeader = 0;
        prepareClipPlay(pcmPrivateData->channels, pcmPrivateData->sample_rate, pcmPrivateData->bits_per_coded_sample, LE);
    }

    uint8_t *buffer = call->data;
    uint32_t size = call->len;

    uint32_t n;
    uint8_t *injectBuffer = malloc(SubFrameLen);
    uint32_t pos;

    for(pos = 0; pos < size; )
    {
        //printf("PCM %s - Position=%d\n", __FUNCTION__, pos);
        if((size - pos) < SubFrameLen)
        {
            breakBufferFillSize = size - pos;
            memcpy(breakBuffer, &buffer[pos], sizeof(uint8_t) * breakBufferFillSize);
            //printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize);
            break;
        }

        //get first PES's worth
        if(breakBufferFillSize > 0)
        {
            memcpy(injectBuffer, breakBuffer, sizeof(uint8_t)*breakBufferFillSize);
            memcpy(&injectBuffer[breakBufferFillSize], &buffer[pos], sizeof(unsigned char)*(SubFrameLen - breakBufferFillSize));
            pos += (SubFrameLen - breakBufferFillSize);
            breakBufferFillSize = 0;
        }
        else
        {
            memcpy(injectBuffer, &buffer[pos], sizeof(uint8_t)*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(16 == pcmPrivateData->bits_per_coded_sample) 
        {
            for(n=0; n<SubFrameLen; n+=2)
            {
                uint8_t 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, call->Pts, 0);
        int32_t len = call->WriteV(call->fd, iov, 3);
        if (len < 0)
        {
            break;
        }
    }
    free(injectBuffer);

    return size;
}
Example #16
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    unsigned char  PesHeader[PES_MAX_HEADER_SIZE];
    unsigned char  FakeHeaders[64]; // 64bytes should be enough to make the fake headers
    unsigned int   FakeHeaderLength;
    unsigned int   ExtraLength = 0;
    unsigned char  Version             = 5;
    unsigned int   FakeStartCode       = (Version << 8) | PES_VERSION_FAKE_START_CODE;
    unsigned int   HeaderLength = 0;
    unsigned int   usecPerFrame = 41708; /* Hellmaster1024: default value */
    BitPacker_t ld = {FakeHeaders, 0, 32};

    divx_printf(10, "\n");

    if (call == NULL)
    {
        divx_err("call data is NULL...\n");
        return 0;
    }

    divx_printf(10, "AudioPts %lld\n", call->Pts);

    if ((call->data == NULL) || (call->len <= 0))
    {
        divx_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        divx_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    usecPerFrame = 1000000000 / call->FrameRate;
    divx_printf(10, "Microsecends per frame = %d\n", usecPerFrame);

    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);

    FakeHeaderLength    = (ld.Ptr - (FakeHeaders));

    if (initialHeader) ExtraLength = call->private_size;

    HeaderLength = InsertPesHeader (PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, FakeStartCode);
    int iovcnt = 0;
    struct iovec iov[4];
    iov[iovcnt].iov_base = PesHeader;
    iov[iovcnt].iov_len  = HeaderLength;
    iovcnt++;
    iov[iovcnt].iov_base = FakeHeaders;
    iov[iovcnt].iov_len  = FakeHeaderLength;
    iovcnt++;

    if (initialHeader) {
        initialHeader = 0;
        iov[iovcnt].iov_base = call->private_data;
        iov[iovcnt].iov_len  = call->private_size;
        iovcnt++;
    }

    iov[iovcnt].iov_base = call->data;
    iov[iovcnt].iov_len  = call->len;
    iovcnt++;
    int len = writev(call->fd, iov, iovcnt); 

    divx_printf(10, "xvid_Write < len=%d\n", len);

    return len;
}
Example #17
0
bool WriterVC1::Write(AVPacket *packet, int64_t pts)
{
	if (!packet || !packet->data)
		return false;

	if (initialHeader) {
		initialHeader = false;
		FrameHeaderSeen = false;

		const uint8_t SequenceLayerStartCode[] =
			{ 0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE };


		const uint8_t 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
		};

		uint8_t PesHeader[PES_MAX_HEADER_SIZE];
		uint8_t PesPayload[128];
		uint8_t *PesPtr;
		unsigned int usecPerFrame = av_rescale(AV_TIME_BASE, stream->r_frame_rate.den, stream->r_frame_rate.num);
		struct iovec iov[2];


		memset(PesPayload, 0, sizeof(PesPayload));

		PesPtr = PesPayload;

		memcpy(PesPtr, SequenceLayerStartCode, sizeof(SequenceLayerStartCode));
		PesPtr += sizeof(SequenceLayerStartCode);

		memcpy(PesPtr, Metadata, sizeof(Metadata));
		PesPtr += METADATA_STRUCT_C_START;
		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;

		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;

		iov[0].iov_base = PesHeader;
		iov[1].iov_base = PesPayload;
		iov[1].iov_len = PesPtr - PesPayload;
		iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
		if (writev(fd, iov, 2) < 0)
			return false;

		/* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */
		iov[0].iov_base = PesHeader;
		iov[1].iov_base = stream->codec->extradata;
		iov[1].iov_len = stream->codec->extradata_size;
		iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0);
		if (writev(fd, iov, 2) < 0)
			return false;

		initialHeader = false;
	}

	if (packet->size > 0) {
		int Position = 0;
		bool insertSampleHeader = true;

		while (Position < packet->size) {
			int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
			uint8_t PesHeader[PES_MAX_HEADER_SIZE];
			int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, pts, 0);

			if (insertSampleHeader) {
				const uint8_t Vc1FrameStartCode[] = { 0, 0, 1, VC1_FRAME_START_CODE };

				if (!FrameHeaderSeen && (packet->size > 3) && (memcmp(packet->data, Vc1FrameStartCode, 4) == 0))
					FrameHeaderSeen = true;
				if (!FrameHeaderSeen) {
					memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode));
					HeaderLength += sizeof(Vc1FrameStartCode);
				}
				insertSampleHeader = false;
			}

			struct iovec iov[2];
			iov[0].iov_base = PesHeader;
			iov[0].iov_len = HeaderLength;
			iov[1].iov_base = packet->data + Position;
			iov[1].iov_len = PacketLength;

			ssize_t l = writev(fd, iov, 2);
			if (l < 0)
				return false;

			Position += PacketLength;
			pts = INVALID_PTS_VALUE;
		}
	}

	return true;
}
Example #18
0
static int writeData(void *_call)
{
	WriterAVCallData_t *call = (WriterAVCallData_t *) _call;

	int len = 0;

	wma_printf(10, "\n");

	if (call == NULL)
	{
		wma_err("call data is NULL...\n");
		return 0;
	}

	wma_printf(10, "AudioPts %lld\n", call->Pts);

	if ((call->data == NULL) || (call->len <= 0))
	{
		wma_err("parsing NULL Data. ignoring...\n");
		return 0;
	}

	if (call->fd < 0)
	{
		wma_err("file pointer < 0. ignoring ...\n");
		return 0;
	}

	if (initialHeader)
	{

		unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

		if ((call->private_size <= 0) || (call->private_data == NULL))
		{
			wma_err("private NULL.\n");
			return -1;
		}

		struct iovec iov[2];
		iov[0].iov_base = PesHeader;
		iov[0].iov_len = InsertPesHeader(PesHeader, call->private_size, MPEG_AUDIO_PES_START_CODE, 0, 0);
		iov[1].iov_base = call->private_data;
		iov[1].iov_len = call->private_size;

		len = writev(call->fd, iov, 2);

		initialHeader = 0;
	}

	if (len > -1 && call->len > 0 && call->data)
	{
		unsigned char  PesHeader[PES_MAX_HEADER_SIZE];

		struct iovec iov[2];
		iov[0].iov_base = PesHeader;
		iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0);
		iov[1].iov_base = call->data;
		iov[1].iov_len = call->len;

		ssize_t l = writev(call->fd, iov, 2);
		if (l > -1)
			len += l;
		else
			len = l;
	}

	wma_printf(10, "wma < %d\n", len);

	return len;
}
Example #19
0
static int writeData(void* _call)
{
    WriterAVCallData_t* call = (WriterAVCallData_t*) _call;

    static uint8_t PesHeader[PES_MAX_HEADER_SIZE];
    int32_t len = 0;
    uint32_t Position = 0;

    mpeg2_printf(10, "\n");

    if (call == NULL)
    {
        mpeg2_err("call data is NULL...\n");
        return 0;
    }

    mpeg2_printf(10, "VideoPts %lld\n", call->Pts);

    if ((call->data == NULL) || (call->len <= 0))
    {
        mpeg2_err("parsing NULL Data. ignoring...\n");
        return 0;
    }

    if (call->fd < 0)
    {
        mpeg2_err("file pointer < 0. ignoring ...\n");
        return 0;
    }

    uint8_t *data = call->data;
    uint32_t data_len = call->len;

    if (!private_data && !call->private_data && data_len > 3 && !memcmp(data, "\x00\x00\x01\xb3", 4))
    {
        bool ok = true;
        uint32_t pos = 4;
        uint32_t sheader_data_len = 0;
        while (pos < data_len && ok)
        {
            if (pos >= data_len) break;
            pos += 7;
            if (pos >=data_len) break;
            sheader_data_len = 12;
            if (data[pos] & 2)
            { // intra matrix
                pos += 64;
                if (pos >=data_len) break;
                sheader_data_len += 64;
            }
            if (data[pos] & 1)
            { // non intra matrix
                pos += 64;
                if (pos >=data_len) break;
                sheader_data_len += 64;
            }
            pos += 1;
            if (pos + 3 >=data_len) break;
            if (!memcmp(&data[pos], "\x00\x00\x01\xb5", 4))
            {
                // extended start code
                pos += 3;
                sheader_data_len += 3;
                do
                {
                    pos += 1;
                    ++sheader_data_len;
                    if (pos + 2 > data_len)
                    {
                        ok = false;
                        break;
                    }
                } while (memcmp(&data[pos], "\x00\x00\x01", 3));
                if (!ok) break;
            }
            if (pos + 3 >= data_len) break;
            if (!memcmp(&data[pos], "\x00\x00\x01\xb2", 4))
            {
                // private data
                pos += 3;
                sheader_data_len += 3;
                do
                {
                    pos += 1;
                    ++sheader_data_len;
                    if (pos + 2 > data_len)
                    {
                        ok = false;
                        break;
                    }
                } while (memcmp(&data[pos], "\x00\x00\x01", 3));
                if (!ok) break;
            }

            free(private_data);
            private_data = malloc(sheader_data_len);
            if (private_data)
            {
                private_size = sheader_data_len;
                memcpy(private_data, data + pos - sheader_data_len, sheader_data_len);
            }
            must_send_header = false;
            break;
        }
    }
    else if ((private_data || call->private_data) && must_send_header)
    {
        uint8_t *codec_data = NULL;
        uint32_t codec_data_size = 0;
        int pos = 0;

        if (private_data) {
            codec_data = private_data;
            codec_data_size = private_size;
        }
        else {
            codec_data = call->private_data;
            codec_data_size = call->private_size;
        }

        while (pos <= data_len - 4)
        {
            if (memcmp(&data[pos], "\x00\x00\x01\xb8", 4)) /* find group start code */
            {
                pos++;
                continue;
            }

            struct iovec iov[4];
            iov[0].iov_base = PesHeader;
            iov[0].iov_len = InsertPesHeader(PesHeader, call->len + codec_data_size, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);

            iov[1].iov_base = data;
            iov[1].iov_len = pos;

            iov[2].iov_base = codec_data;
            iov[2].iov_len = codec_data_size;

            iov[3].iov_base = data + pos;
            iov[3].iov_len = data_len - pos;

            must_send_header = false;
            return call->WriteV(call->fd, iov, 4);
        }
    }

    struct iovec iov[2];

    iov[0].iov_base = PesHeader;
    iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0);

    iov[1].iov_base = data;
    iov[1].iov_len = data_len;

    PesHeader[6] = 0x81;
    
    UpdatePesHeaderPayloadSize(PesHeader, data_len + iov[0].iov_len - 6);
    if (iov[0].iov_len != WriteExt(call->WriteV, call->fd, iov[0].iov_base, iov[0].iov_len)) return -1;
    if (iov[1].iov_len != WriteExt(call->WriteV, call->fd, iov[1].iov_base, iov[1].iov_len)) return -1;

    return 1;
}