static void hap_write_frame_header(HapContext *ctx, uint8_t *dst, int frame_length) { PutByteContext pbc; int i; bytestream2_init_writer(&pbc, dst, frame_length); if (ctx->chunk_count == 1) { /* Write a simple header */ hap_write_section_header(&pbc, HAP_HDR_LONG, frame_length - 8, ctx->chunks[0].compressor | ctx->opt_tex_fmt); } else { /* Write a complex header with Decode Instructions Container */ hap_write_section_header(&pbc, HAP_HDR_LONG, frame_length - 8, HAP_COMP_COMPLEX | ctx->opt_tex_fmt); hap_write_section_header(&pbc, HAP_HDR_SHORT, hap_decode_instructions_length(ctx), HAP_ST_DECODE_INSTRUCTIONS); hap_write_section_header(&pbc, HAP_HDR_SHORT, ctx->chunk_count, HAP_ST_COMPRESSOR_TABLE); for (i = 0; i < ctx->chunk_count; i++) { bytestream2_put_byte(&pbc, ctx->chunks[i].compressor >> 4); } hap_write_section_header(&pbc, HAP_HDR_SHORT, ctx->chunk_count * 4, HAP_ST_SIZE_TABLE); for (i = 0; i < ctx->chunk_count; i++) { bytestream2_put_le32(&pbc, ctx->chunks[i].compressed_size); } } }
/* This function creates a magic cookie basec on the codec parameter and formatID * Return value: a pointer to a magic cookie which has to be av_free()'d * in cookieSize, the size of the magic cookie is returned to the caller */ uint8_t *create_cookie(AVCodecContext *codec, size_t *cookieSize, UInt32 formatID, int vbr) { uint8_t *waveAtom = NULL; PutByteContext p; int waveSize; if (formatID == kAudioFormatMPEG4AAC) { return CreateEsdsFromSetupData(codec->extradata, codec->extradata_size, cookieSize, 1, true, false); } /* Do we need an endia atom, too? */ /* initialize the user Atom * 8 bytes for the atom size & atom type * 18 bytes for the already extracted part, see wav.c in the ffmpeg project * extradata_size for the data still stored in the AVCodecContext structure */ waveSize = 18 + codec->extradata_size + 8; waveAtom = av_malloc(waveSize); if (!waveAtom) goto bail; bytestream2_init_writer(&p, waveAtom, waveSize); /* now construct the wave atom */ /* QT Atoms are big endian, I think but the WAVE data should be little endian */ bytestream2_put_be32(&p, waveSize); bytestream2_put_be32(&p, formatID); bytestream2_put_le32(&p, codec->codec_tag); bytestream2_put_le32(&p, codec->channels); bytestream2_put_le32(&p, codec->sample_rate); bytestream2_put_le32(&p, vbr ? 0 : codec->bit_rate / 8); bytestream2_put_le16(&p, codec->block_align); bytestream2_put_le16(&p, codec->bits_per_coded_sample); bytestream2_put_le16(&p, codec->extradata_size); /* now the remaining stuff */ bytestream2_put_buffer(&p, codec->extradata, codec->extradata_size); bail: *cookieSize = waveSize; return waveAtom; } /* create_cookie() */
/* section_length does not include the header */ static void hap_write_section_header(PutByteContext *pbc, enum HapHeaderLength header_length, int section_length, enum HapSectionType section_type) { /* The first three bytes are the length of the section (not including the * header) or zero if using an eight-byte header. * For an eight-byte header, the length is in the last four bytes. * The fourth byte stores the section type. */ bytestream2_put_le24(pbc, header_length == HAP_HDR_LONG ? 0 : section_length); bytestream2_put_byte(pbc, section_type); if (header_length == HAP_HDR_LONG) { bytestream2_put_le32(pbc, section_length); } }
/* This function creates an image description extension that some codecs need to be able * to decode properly, a copy of the strf (BITMAPINFOHEADER) chunk in the avi. * Return value: a handle to an image description extension which has to be DisposeHandle()'d * in cookieSize, the size of the image description extension is returned to the caller */ Handle create_strf_ext(AVCodecContext *codec) { Handle result = NULL; PutByteContext p; int size; /* initialize the extension * 40 bytes for the BITMAPINFOHEADER stucture, see avienc.c in the ffmpeg project * extradata_size for the data still stored in the AVCodecContext structure */ size = 40 + codec->extradata_size; result = NewHandle(size); if (result == NULL) goto bail; bytestream2_init_writer(&p, (uint8_t*)*result, size); /* construct the BITMAPINFOHEADER structure */ /* QT Atoms are big endian, but the STRF atom should be little endian */ bytestream2_put_be32(&p, size); bytestream2_put_le32(&p, codec->width); bytestream2_put_le32(&p, codec->width); bytestream2_put_le16(&p, 1); // planes bytestream2_put_le16(&p, codec->bits_per_coded_sample ?: 24); /* compression type */ bytestream2_put_le32(&p, codec->codec_tag); bytestream2_put_le32(&p, codec->width * codec->height * 3); bytestream2_put_le32(&p, 0); bytestream2_put_le32(&p, 0); bytestream2_put_le32(&p, 0); bytestream2_put_le32(&p, 0); /* now the remaining stuff */ bytestream2_put_buffer(&p, codec->extradata, codec->extradata_size); if (codec->extradata_size & 1) { bytestream2_put_byte(&p, 0); } bail: return result; } /* create_extension() */