Ticket #372: spdifenc3.patch

File spdifenc3.patch, 3.0 KB (added by naoya, 15 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) {