You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
lavc/videotoolbox: escape 0x00000[0-3]s in avcC PSs
This commit is contained in:
@@ -140,14 +140,51 @@ int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
|
|||||||
|
|
||||||
#define AV_W8(p, v) *(p) = (v)
|
#define AV_W8(p, v) *(p) = (v)
|
||||||
|
|
||||||
|
static int escape_ps(uint8_t* dst, const uint8_t* src, int src_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int size = src_size;
|
||||||
|
uint8_t* p = dst;
|
||||||
|
|
||||||
|
for (i = 0; i < src_size; i++) {
|
||||||
|
if (i + 2 < src_size &&
|
||||||
|
src[i] == 0x00 &&
|
||||||
|
src[i + 1] == 0x00 &&
|
||||||
|
src[i + 2] <= 0x03) {
|
||||||
|
if (dst) {
|
||||||
|
*p++ = src[i++];
|
||||||
|
*p++ = src[i++];
|
||||||
|
*p++ = 0x03;
|
||||||
|
} else {
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
if (dst)
|
||||||
|
*p++ = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst)
|
||||||
|
av_assert0((p - dst) == size);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
|
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
VTContext *vtctx = avctx->internal->hwaccel_priv_data;
|
VTContext *vtctx = avctx->internal->hwaccel_priv_data;
|
||||||
H264Context *h = avctx->priv_data;
|
H264Context *h = avctx->priv_data;
|
||||||
CFDataRef data = NULL;
|
CFDataRef data = NULL;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
int vt_extradata_size = 6 + 2 + h->ps.sps->data_size + 3 + h->ps.pps->data_size;
|
int sps_size = escape_ps(NULL, h->ps.sps->data, h->ps.sps->data_size);
|
||||||
uint8_t *vt_extradata = av_malloc(vt_extradata_size);
|
int pps_size = escape_ps(NULL, h->ps.pps->data, h->ps.pps->data_size);
|
||||||
|
int vt_extradata_size;
|
||||||
|
uint8_t *vt_extradata;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
vt_extradata_size = 6 + 2 + sps_size + 3 + pps_size;
|
||||||
|
vt_extradata = av_malloc(vt_extradata_size);
|
||||||
|
|
||||||
if (!vt_extradata)
|
if (!vt_extradata)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -159,14 +196,14 @@ CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
|
|||||||
AV_W8(p + 3, h->ps.sps->data[3]); /* level */
|
AV_W8(p + 3, h->ps.sps->data[3]); /* level */
|
||||||
AV_W8(p + 4, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 3 (11) */
|
AV_W8(p + 4, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 3 (11) */
|
||||||
AV_W8(p + 5, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
|
AV_W8(p + 5, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
|
||||||
AV_WB16(p + 6, h->ps.sps->data_size);
|
AV_WB16(p + 6, sps_size);
|
||||||
memcpy(p + 8, h->ps.sps->data, h->ps.sps->data_size);
|
p += 8;
|
||||||
p += 8 + h->ps.sps->data_size;
|
p += escape_ps(p, h->ps.sps->data, h->ps.sps->data_size);
|
||||||
AV_W8(p + 0, 1); /* number of pps */
|
AV_W8(p + 0, 1); /* number of pps */
|
||||||
AV_WB16(p + 1, h->ps.pps->data_size);
|
AV_WB16(p + 1, pps_size);
|
||||||
memcpy(p + 3, h->ps.pps->data, h->ps.pps->data_size);
|
p += 3;
|
||||||
|
p += escape_ps(p, h->ps.pps->data, h->ps.pps->data_size);
|
||||||
|
|
||||||
p += 3 + h->ps.pps->data_size;
|
|
||||||
av_assert0(p - vt_extradata == vt_extradata_size);
|
av_assert0(p - vt_extradata == vt_extradata_size);
|
||||||
|
|
||||||
// save sps header (profile/level) used to create decoder session,
|
// save sps header (profile/level) used to create decoder session,
|
||||||
|
Reference in New Issue
Block a user