Ticket #372: spdifenc3.patch

File spdifenc3.patch, 3.0 KB (added by naoya, 5 years ago)
  • libavformat/spdifenc.c

    diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
    index 84372f8..659691c 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#define AC3_HEADER_SIZE 7 
     58 
    5659typedef struct IEC61937Context { 
    5760    const AVClass *av_class; 
    5861    enum IEC61937DataType data_type;///< burst info - reference to type of payload of the data-burst 
    static const AVClass class = { 
    103106static int spdif_header_ac3(AVFormatContext *s, AVPacket *pkt) 
    104107{ 
    105108    IEC61937Context *ctx = s->priv_data; 
    106     int bitstream_mode = pkt->data[5] & 0x7; 
     109    AC3HeaderInfo hdr; 
     110    GetBitContext gbc; 
     111    int ret; 
    107112 
    108     ctx->data_type  = IEC61937_AC3 | (bitstream_mode << 8); 
    109     ctx->pkt_offset = AC3_FRAME_SIZE << 2; 
     113    if (pkt->size < AC3_HEADER_SIZE) 
     114        return AVERROR_INVALIDDATA; 
     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, "Invalid AC3 header\n"); 
     119        return AVERROR_INVALIDDATA; 
     120    } 
     121    if (hdr.num_blocks != 6) { 
     122        av_log(s, AV_LOG_ERROR, "AC3 num_blocks[%d] not supported for IEC-61937\n", hdr.num_blocks); 
     123        return AVERROR_INVALIDDATA; 
     124    } 
     125    ctx->data_type   = IEC61937_AC3 | (hdr.bitstream_mode <<8); 
     126    ctx->pkt_offset  = AC3_FRAME_SIZE <<2; 
     127    ctx->out_bytes   = hdr.frame_size; 
     128    ctx->length_code = ctx->out_bytes <<3; 
    110129    return 0; 
    111130} 
    112131 
    static int spdif_header_mpeg(AVFormatContext *s, AVPacket *pkt) 
    326345    int extension = pkt->data[2] & 1; 
    327346 
    328347    if (layer == 3 || version == 1) { 
    329         av_log(s, AV_LOG_ERROR, "Wrong MPEG file format\n"); 
     348        av_log(s, AV_LOG_ERROR, "Invalid MPEG header\n"); 
    330349        return AVERROR_INVALIDDATA; 
    331350    } 
    332351    av_log(s, AV_LOG_DEBUG, "version: %i layer: %i extension: %i\n", version, layer, extension); 
    static int spdif_header_aac(AVFormatContext *s, AVPacket *pkt) 
    351370    init_get_bits(&gbc, pkt->data, AAC_ADTS_HEADER_SIZE * 8); 
    352371    ret = ff_aac_parse_header(&gbc, &hdr); 
    353372    if (ret < 0) { 
    354         av_log(s, AV_LOG_ERROR, "Wrong AAC file format\n"); 
     373        av_log(s, AV_LOG_ERROR, "Invalid AAC header\n"); 
    355374        return AVERROR_INVALIDDATA; 
    356375    } 
    357376 
    358     ctx->pkt_offset = hdr.samples << 2; 
     377    ctx->out_bytes   = ret; 
     378    ctx->pkt_offset  = hdr.samples << 2; 
     379    ctx->length_code = ctx->out_bytes << 3; 
    359380    switch (hdr.num_aac_frames) { 
    360381    case 1: 
    361382        ctx->data_type = IEC61937_MPEG2_AAC; 
    static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt) 
    503524        return ret; 
    504525    if (!ctx->pkt_offset) 
    505526        return 0; 
     527    if (pkt->size < ctx->out_bytes) 
     528        return AVERROR_INVALIDDATA; 
    506529 
    507530    padding = (ctx->pkt_offset - ctx->use_preamble * BURST_HEADER_SIZE - ctx->out_bytes) & ~1; 
    508531    if (padding < 0) {