
- Correctly writes global headers. Ticket #61 - Add support for recording AAC audio. Ticket #160
155 lines
3.6 KiB
C
155 lines
3.6 KiB
C
/*****************************************************************************
|
|
* matroska_ebml.c:
|
|
*****************************************************************************
|
|
* Copyright (C) 2005 Mike Matsnev
|
|
* Copyright (C) 2010 Andreas Öman
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
|
|
*****************************************************************************/
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "ebml.h"
|
|
|
|
void
|
|
ebml_append_id(htsbuf_queue_t *q, uint32_t id)
|
|
{
|
|
uint8_t u8[4] = {id >> 24, id >> 16, id >> 8, id};
|
|
|
|
if(u8[0])
|
|
return htsbuf_append(q, u8, 4);
|
|
if(u8[1])
|
|
return htsbuf_append(q, u8+1, 3);
|
|
if(u8[2])
|
|
return htsbuf_append(q, u8+2, 2);
|
|
return htsbuf_append(q, u8+3, 1);
|
|
}
|
|
|
|
void
|
|
ebml_append_size(htsbuf_queue_t *q, uint32_t size)
|
|
{
|
|
uint8_t u8[5] = { 0x08, size >> 24, size >> 16, size >> 8, size };
|
|
|
|
if(size < 0x7f) {
|
|
u8[4] |= 0x80;
|
|
return htsbuf_append(q, u8+4, 1);
|
|
}
|
|
|
|
if(size < 0x3fff) {
|
|
u8[3] |= 0x40;
|
|
return htsbuf_append(q, u8+3, 2);
|
|
}
|
|
if(size < 0x1fffff) {
|
|
u8[2] |= 0x20;
|
|
return htsbuf_append(q, u8+2, 3);
|
|
}
|
|
if(size < 0x0fffffff) {
|
|
u8[1] |= 0x10;
|
|
return htsbuf_append(q, u8+1, 4);
|
|
}
|
|
return htsbuf_append(q, u8, 5);
|
|
}
|
|
|
|
|
|
void
|
|
ebml_append_bin(htsbuf_queue_t *q, unsigned id, const void *data, size_t len)
|
|
{
|
|
ebml_append_id(q, id);
|
|
ebml_append_size(q, len);
|
|
return htsbuf_append(q, data, len);
|
|
}
|
|
|
|
void
|
|
ebml_append_string(htsbuf_queue_t *q, unsigned id, const char *str)
|
|
{
|
|
return ebml_append_bin(q, id, str, strlen(str));
|
|
}
|
|
|
|
void
|
|
ebml_append_uint(htsbuf_queue_t *q, unsigned id, int64_t ui)
|
|
{
|
|
uint8_t u8[8] = {ui >> 56, ui >> 48, ui >> 40, ui >> 32,
|
|
ui >> 24, ui >> 16, ui >> 8, ui };
|
|
int i = 0;
|
|
while( i < 7 && !u8[i] )
|
|
++i;
|
|
return ebml_append_bin(q, id, u8 + i, 8 - i);
|
|
}
|
|
|
|
void
|
|
ebml_append_float(htsbuf_queue_t *q, unsigned id, float f)
|
|
{
|
|
union
|
|
{
|
|
float f;
|
|
unsigned u;
|
|
} u;
|
|
unsigned char c_f[4];
|
|
|
|
u.f = f;
|
|
c_f[0] = u.u >> 24;
|
|
c_f[1] = u.u >> 16;
|
|
c_f[2] = u.u >> 8;
|
|
c_f[3] = u.u;
|
|
|
|
return ebml_append_bin(q, id, c_f, 4);
|
|
}
|
|
|
|
void
|
|
ebml_append_master(htsbuf_queue_t *q, uint32_t id, htsbuf_queue_t *p)
|
|
{
|
|
ebml_append_id(q, id);
|
|
ebml_append_size(q, p->hq_size);
|
|
htsbuf_appendq(q, p);
|
|
free(p);
|
|
}
|
|
|
|
void
|
|
ebml_append_void(htsbuf_queue_t *q)
|
|
{
|
|
char n[1] = {0};
|
|
ebml_append_bin(q, 0xec, n, 1);
|
|
}
|
|
|
|
|
|
void
|
|
ebml_append_pad(htsbuf_queue_t *q, size_t pad)
|
|
{
|
|
assert(pad > 2);
|
|
pad -= 2;
|
|
assert(pad < 0x3fff);
|
|
pad -= pad > 0x7e;
|
|
|
|
void *data = alloca(pad);
|
|
memset(data, 0, pad);
|
|
ebml_append_bin(q, 0xec, data, pad);
|
|
}
|
|
|
|
|
|
void
|
|
ebml_append_idid(htsbuf_queue_t *q, uint32_t id0, uint32_t id)
|
|
{
|
|
uint8_t u8[4] = {id >> 24, id >> 16, id >> 8, id};
|
|
|
|
if(u8[0])
|
|
return ebml_append_bin(q, id0, u8, 4);
|
|
if(u8[1])
|
|
return ebml_append_bin(q, id0, u8+1, 3);
|
|
if(u8[2])
|
|
return ebml_append_bin(q, id0, u8+2, 2);
|
|
return ebml_append_bin(q, id0, u8+3, 1);
|
|
}
|