Skip to content

Commit

Permalink
feat: TS dynamic alloc PMT
Browse files Browse the repository at this point in the history
  • Loading branch information
ireader committed Nov 7, 2020
1 parent 3a15f1d commit f0880ef
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 19 deletions.
5 changes: 4 additions & 1 deletion libmpeg/include/mpeg-ts-proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ struct pat_t
unsigned int cc; //continuity_counter : 4;

unsigned int pmt_count;
struct pmt_t pmts[4];
unsigned int pmt_capacity;
struct pmt_t pmt_default[1];
struct pmt_t* pmts;
};

// Table 2-3 - PID table(p36)
Expand Down Expand Up @@ -187,6 +189,7 @@ enum
MPEG_FLAG_H264_H265_WITH_AUD = 0x8000,
};

struct pmt_t* pat_alloc_pmt(struct pat_t* pat);
struct pmt_t* pat_find(struct pat_t* pat, uint16_t pn);
size_t pat_read(struct pat_t *pat, const uint8_t* data, size_t bytes);
size_t pat_write(const struct pat_t *pat, uint8_t *data);
Expand Down
57 changes: 46 additions & 11 deletions libmpeg/source/mpeg-pat.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,61 @@

#include "mpeg-ts-proto.h"
#include "mpeg-util.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

struct pmt_t* pat_alloc_pmt(struct pat_t* pat)
{
void* ptr;
unsigned int n;

if (NULL == pat->pmts)
{
assert(0 == pat->pmt_count);
assert(0 == pat->pmt_capacity);
pat->pmts = pat->pmt_default;
pat->pmt_capacity = sizeof(pat->pmt_default) / sizeof(pat->pmt_default[0]);
}

if (pat->pmt_count >= pat->pmt_capacity)
{
if (pat->pmt_count + 1 > 65535)
{
assert(0);
return NULL;
}

n = pat->pmt_capacity + pat->pmt_capacity / 4 + 4;
ptr = realloc(pat->pmts == pat->pmt_default ? NULL : pat->pmts, sizeof(pat->pmts[0]) * n);
if (!ptr)
return NULL;

if (pat->pmts == pat->pmt_default)
memmove(ptr, pat->pmts, sizeof(pat->pmt_default));
pat->pmts = (struct pmt_t*)ptr;
pat->pmt_capacity = n;
}

// new pmt
memset(&pat->pmts[pat->pmt_count], 0, sizeof(pat->pmts[0]));
return &pat->pmts[pat->pmt_count];
}

static struct pmt_t* pat_fetch(struct pat_t* pat, uint16_t pid)
{
unsigned int i;
for(i = 0; i < pat->pmt_count; i++)
unsigned int i;
struct pmt_t* pmt;
for(i = 0; i < pat->pmt_count; i++)
{
if(pat->pmts[i].pid == pid)
return &pat->pmts[i];
}

if(pat->pmt_count >= sizeof(pat->pmts) / sizeof(pat->pmts[0]))
{
assert(0);
return NULL;
}


// new pmt
return &pat->pmts[pat->pmt_count++];
pmt = pat_alloc_pmt(pat);
pat->pmt_count++;
return pmt;
}

size_t pat_read(struct pat_t *pat, const uint8_t* data, size_t bytes)
Expand Down Expand Up @@ -65,7 +101,6 @@ size_t pat_read(struct pat_t *pat, const uint8_t* data, size_t bytes)

if(0 == pn)
continue; // ignore NIT info
assert(pat->pmt_count <= sizeof(pat->pmts)/sizeof(pat->pmts[0]));
pmt = pat_fetch(pat, pid);
if(NULL == pmt)
continue;
Expand Down
3 changes: 3 additions & 0 deletions libmpeg/source/mpeg-ts-dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ int ts_demuxer_destroy(struct ts_demuxer_t* ts)
}
}

if (ts->pat.pmts && ts->pat.pmts != ts->pat.pmt_default)
free(ts->pat.pmts);

free(ts);
return 0;
}
Expand Down
15 changes: 8 additions & 7 deletions libmpeg/source/mpeg-ts-enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ int mpeg_ts_destroy(void* ts)
mpeg_ts_pmt_destroy(pmt);
}

if (tsctx->pat.pmts && tsctx->pat.pmts != tsctx->pat.pmt_default)
free(tsctx->pat.pmts);
free(tsctx);
return 0;
}
Expand All @@ -385,6 +387,9 @@ int mpeg_ts_add_program(void* ts, uint16_t pn, const void* info, int bytes)
struct pmt_t* pmt;
mpeg_ts_enc_context_t* tsctx;

if (pn < 1 || bytes < 0 || bytes >= (1 << 12))
return -1; // EINVAL: pminfo-len 12-bits

tsctx = (mpeg_ts_enc_context_t*)ts;
for (i = 0; i < tsctx->pat.pmt_count; i++)
{
Expand All @@ -393,15 +398,11 @@ int mpeg_ts_add_program(void* ts, uint16_t pn, const void* info, int bytes)
return -1; // EEXIST
}

if (i >= sizeof(tsctx->pat.pmts) / sizeof(tsctx->pat.pmts[0]))
assert(tsctx->pat.pmt_count == i);
pmt = pat_alloc_pmt(&tsctx->pat);
if (!pmt)
return -1; // E2BIG

if (pn < 1 || bytes < 0 || bytes >= (1 << 12))
return -1; // EINVAL: pminfo-len 12-bits

assert(tsctx->pat.pmt_count == i);
pmt = &tsctx->pat.pmts[tsctx->pat.pmt_count];
memset(pmt, 0, sizeof(*pmt));
pmt->pid = tsctx->pid++;
pmt->pn = pn;
pmt->ver = 0x00;
Expand Down

0 comments on commit f0880ef

Please sign in to comment.