Ticket #372: spdifenc.patch

File spdifenc.patch, 3.7 KB (added by naoya, 5 years ago)

spdifenc.patch

  • libavformat/spdifenc.c

    diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
    index 04d4845..018b96c 100644
    a b  
    4848#include "avio_internal.h" 
    4949#include "spdif.h" 
    5050#include "libavcodec/ac3.h" 
     51#include "libavcodec/ac3_parser.h" 
    5152#include "libavcodec/dca.h" 
    5253#include "libavcodec/dcadata.h" 
    5354#include "libavcodec/aacadtsdec.h" 
    5455#include "libavutil/opt.h" 
    5556 
     57#ifndef AC3_HEADER_SIZE 
     58#define AC3_HEADER_SIZE 7 
     59#endif 
     60 
    5661typedef struct IEC61937Context { 
    5762    const AVClass *av_class; 
    5863    enum IEC61937DataType data_type;///< burst info - reference to type of payload of the data-burst 
    static const AVClass class = { 
    103108static int spdif_header_ac3(AVFormatContext *s, AVPacket *pkt) 
    104109{ 
    105110    IEC61937Context *ctx = s->priv_data; 
    106     int bitstream_mode = pkt->data[5] & 0x7; 
     111    AC3HeaderInfo hdr; 
     112    GetBitContext gbc; 
     113    int ret; 
    107114 
    108     ctx->data_type  = IEC61937_AC3 | (bitstream_mode << 8); 
    109     ctx->pkt_offset = AC3_FRAME_SIZE << 2; 
     115    init_get_bits(&gbc, pkt->data, AC3_HEADER_SIZE * 8); 
     116    ret = ff_ac3_parse_header(&gbc, &hdr); 
     117    if (ret) { 
     118        av_log(s, AV_LOG_ERROR, "Wrong AC3 file format\n"); 
     119        return AVERROR_INVALIDDATA; 
     120    } 
     121    ctx->data_type   = IEC61937_AC3 | (hdr.bitstream_mode <<8); 
     122    ctx->pkt_offset  = hdr.num_blocks * 256 << 2; 
     123    ctx->out_bytes   = hdr.frame_size; 
     124    ctx->length_code = ctx->out_bytes <<3; 
    110125    return 0; 
    111126} 
    112127 
    static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt) 
    355370        return AVERROR_INVALIDDATA; 
    356371    } 
    357372 
    358     ctx->pkt_offset = hdr.samples << 2; 
     373    ctx->out_bytes   = ret; 
     374    ctx->pkt_offset  = hdr.samples << 2; 
     375    ctx->length_code = ctx->out_bytes <<3; 
    359376    switch (hdr.num_aac_frames) { 
    360377    case 1: 
    361378        ctx->data_type = IEC61937_MPEG2_AAC; 
    static int spdif_write_header(AVFormatContext *s) 
    473490static int spdif_write_trailer(AVFormatContext *s) 
    474491{ 
    475492    IEC61937Context *ctx = s->priv_data; 
    476     av_freep(&ctx->buffer); 
    477     av_freep(&ctx->hd_buf); 
     493    av_free(ctx->buffer); 
     494    av_free(ctx->hd_buf); 
    478495    return 0; 
    479496} 
    480497 
    static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) 
    494511 
    495512    ctx->out_buf = pkt->data; 
    496513    ctx->out_bytes = pkt->size; 
    497     ctx->length_code = FFALIGN(pkt->size, 2) << 3; 
    498514    ctx->use_preamble = 1; 
    499515    ctx->extra_bswap = 0; 
    500516 
    static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) 
    503519        return ret; 
    504520    if (!ctx->pkt_offset) 
    505521        return 0; 
     522    if (pkt->size < ctx->out_bytes) 
     523        return -1; 
    506524 
    507525    padding = (ctx->pkt_offset - ctx->use_preamble * BURST_HEADER_SIZE - ctx->out_bytes) & ~1; 
    508526    if (padding < 0) { 
    static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) 
    518536    } 
    519537 
    520538    if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) { 
    521     avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1); 
     539        avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1); 
    522540    } else { 
    523     av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE); 
    524     if (!ctx->buffer) 
    525         return AVERROR(ENOMEM); 
    526     ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1); 
    527     avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1); 
     541        ctx->buffer = av_mallocz(ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE); 
     542        if (!ctx->buffer) 
     543            return AVERROR(ENOMEM); 
     544        ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1); 
     545        avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1); 
    528546    } 
    529547 
    530548    /* a final lone byte has to be MSB aligned */