/*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define READ
#define READWRITE read
-#define RWContext BitstreamContext
+#define RWContext GetBitContext
#define xui(width, name, var) do { \
uint32_t value = 0; \
} while (0)
#define nextbits(width, compare, var) \
- (bitstream_bits_left(rw) >= width && \
- (var = bitstream_peek(rw, width)) == (compare))
+ (get_bits_left(rw) >= width && \
+ (var = show_bits(rw, width)) == (compare))
#include "cbs_mpeg2_syntax_template.c"
#undef nextbits
+static void cbs_mpeg2_free_user_data(void *unit, uint8_t *content)
+{
+ MPEG2RawUserData *user = (MPEG2RawUserData*)content;
+ av_buffer_unref(&user->user_data_ref);
+ av_freep(&content);
+}
+
+static void cbs_mpeg2_free_slice(void *unit, uint8_t *content)
+{
+ MPEG2RawSlice *slice = (MPEG2RawSlice*)content;
+ av_buffer_unref(&slice->header.extra_information_ref);
+ av_buffer_unref(&slice->data_ref);
+ av_freep(&content);
+}
+
static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
CodedBitstreamFragment *frag,
int header)
memset(unit_data + unit_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type,
- unit_data, unit_size);
+ unit_data, unit_size, NULL);
if (err < 0) {
av_freep(&unit_data);
return err;
static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx,
CodedBitstreamUnit *unit)
{
- BitstreamContext bc;
+ GetBitContext gbc;
int err;
- err = bitstream_init(&bc, unit->data, 8 * unit->data_size);
+ err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
if (err < 0)
return err;
MPEG2RawSlice *slice;
int pos, len;
- slice = av_mallocz(sizeof(*slice));
- if (!slice)
- return AVERROR(ENOMEM);
- err = cbs_mpeg2_read_slice_header(ctx, &bc, &slice->header);
- if (err < 0) {
- av_free(slice);
+ err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice),
+ &cbs_mpeg2_free_slice);
+ if (err < 0)
+ return err;
+ slice = unit->content;
+
+ err = cbs_mpeg2_read_slice_header(ctx, &gbc, &slice->header);
+ if (err < 0)
return err;
- }
- pos = bitstream_tell(&bc);
+ pos = get_bits_count(&gbc);
len = unit->data_size;
slice->data_size = len - pos / 8;
- slice->data = av_malloc(slice->data_size +
- AV_INPUT_BUFFER_PADDING_SIZE);
- if (!slice->data) {
- av_free(slice);
+ slice->data_ref = av_buffer_alloc(slice->data_size +
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!slice->data_ref)
return AVERROR(ENOMEM);
- }
+ slice->data = slice->data_ref->data;
memcpy(slice->data,
unit->data + pos / 8, slice->data_size);
AV_INPUT_BUFFER_PADDING_SIZE);
slice->data_bit_start = pos % 8;
- unit->content = slice;
-
} else {
switch (unit->type) {
-#define START(start_code, type, func) \
+#define START(start_code, type, read_func, free_func) \
case start_code: \
{ \
type *header; \
- header = av_mallocz(sizeof(*header)); \
- if (!header) \
- return AVERROR(ENOMEM); \
- err = cbs_mpeg2_read_ ## func(ctx, &bc, header); \
- if (err < 0) { \
- av_free(header); \
+ err = ff_cbs_alloc_unit_content(ctx, unit, \
+ sizeof(*header), free_func); \
+ if (err < 0) \
+ return err; \
+ header = unit->content; \
+ err = cbs_mpeg2_read_ ## read_func(ctx, &gbc, header); \
+ if (err < 0) \
return err; \
- } \
- unit->content = header; \
} \
break;
- START(0x00, MPEG2RawPictureHeader, picture_header);
- START(0xb2, MPEG2RawUserData, user_data);
- START(0xb3, MPEG2RawSequenceHeader, sequence_header);
- START(0xb5, MPEG2RawExtensionData, extension_data);
- START(0xb8, MPEG2RawGroupOfPicturesHeader, group_of_pictures_header);
+ START(0x00, MPEG2RawPictureHeader, picture_header, NULL);
+ START(0xb2, MPEG2RawUserData, user_data,
+ &cbs_mpeg2_free_user_data);
+ START(0xb3, MPEG2RawSequenceHeader, sequence_header, NULL);
+ START(0xb5, MPEG2RawExtensionData, extension_data, NULL);
+ START(0xb8, MPEG2RawGroupOfPicturesHeader,
+ group_of_pictures_header, NULL);
#undef START
default:
av_log(ctx->log_ctx, AV_LOG_ERROR, "Unknown start code %02"PRIx32".\n",
PutBitContext *pbc)
{
MPEG2RawSlice *slice = unit->content;
- BitstreamContext bc;
+ GetBitContext gbc;
size_t bits_left;
int err;
if (slice->data_size * 8 + 8 > put_bits_left(pbc))
return AVERROR(ENOSPC);
- bitstream_init(&bc, slice->data, slice->data_size * 8);
- bitstream_skip(&bc, slice->data_bit_start);
+ init_get_bits(&gbc, slice->data, slice->data_size * 8);
+ skip_bits_long(&gbc, slice->data_bit_start);
- while (bitstream_bits_left(&bc) > 15)
- put_bits(pbc, 16, bitstream_read(&bc, 16));
+ while (get_bits_left(&gbc) > 15)
+ put_bits(pbc, 16, get_bits(&gbc, 16));
- bits_left = bitstream_bits_left(&bc);
- put_bits(pbc, bits_left, bitstream_read(&bc, bits_left));
+ bits_left = get_bits_left(&gbc);
+ put_bits(pbc, bits_left, get_bits(&gbc, bits_left));
// Align with zeroes.
while (put_bits_count(pbc) % 8 != 0)
if (err < 0) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a "
"sufficiently large write buffer (last attempt "
- "%zu bytes).\n", priv->write_buffer_size);
+ "%"SIZE_SPECIFIER" bytes).\n", priv->write_buffer_size);
return err;
}
}
unit->data_size = (put_bits_count(&pbc) + 7) / 8;
flush_put_bits(&pbc);
- err = av_reallocp(&unit->data, unit->data_size);
+ err = ff_cbs_alloc_unit_data(ctx, unit, unit->data_size);
if (err < 0)
return err;
for (i = 0; i < frag->nb_units; i++)
size += 3 + frag->units[i].data_size;
- data = av_malloc(size);
- if (!data)
+ frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!frag->data_ref)
return AVERROR(ENOMEM);
+ data = frag->data_ref->data;
dp = 0;
for (i = 0; i < frag->nb_units; i++) {
av_assert0(dp == size);
+ memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
frag->data = data;
frag->data_size = size;
return 0;
}
-static void cbs_mpeg2_free_unit(CodedBitstreamUnit *unit)
-{
- if (MPEG2_START_IS_SLICE(unit->type)) {
- MPEG2RawSlice *slice = unit->content;
- av_freep(&slice->data);
- av_freep(&slice->header.extra_information);
- } else if (unit->type == MPEG2_START_USER_DATA) {
- MPEG2RawUserData *user = unit->content;
- av_freep(&user->user_data);
- }
- av_freep(&unit->content);
-}
-
static void cbs_mpeg2_close(CodedBitstreamContext *ctx)
{
CodedBitstreamMPEG2Context *priv = ctx->priv_data;
.write_unit = &cbs_mpeg2_write_unit,
.assemble_fragment = &cbs_mpeg2_assemble_fragment,
- .free_unit = &cbs_mpeg2_free_unit,
.close = &cbs_mpeg2_close,
};