You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +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)
|
||||
|
||||
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)
|
||||
{
|
||||
VTContext *vtctx = avctx->internal->hwaccel_priv_data;
|
||||
H264Context *h = avctx->priv_data;
|
||||
CFDataRef data = NULL;
|
||||
uint8_t *p;
|
||||
int vt_extradata_size = 6 + 2 + h->ps.sps->data_size + 3 + h->ps.pps->data_size;
|
||||
uint8_t *vt_extradata = av_malloc(vt_extradata_size);
|
||||
int sps_size = escape_ps(NULL, h->ps.sps->data, h->ps.sps->data_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)
|
||||
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 + 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_WB16(p + 6, h->ps.sps->data_size);
|
||||
memcpy(p + 8, h->ps.sps->data, h->ps.sps->data_size);
|
||||
p += 8 + h->ps.sps->data_size;
|
||||
AV_WB16(p + 6, sps_size);
|
||||
p += 8;
|
||||
p += escape_ps(p, h->ps.sps->data, h->ps.sps->data_size);
|
||||
AV_W8(p + 0, 1); /* number of pps */
|
||||
AV_WB16(p + 1, h->ps.pps->data_size);
|
||||
memcpy(p + 3, h->ps.pps->data, h->ps.pps->data_size);
|
||||
AV_WB16(p + 1, pps_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);
|
||||
|
||||
// save sps header (profile/level) used to create decoder session,
|
||||
|
Reference in New Issue
Block a user