/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */ static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]) { const enum AVPixelFormat srcFormat = c->srcFormat; const enum AVPixelFormat dstFormat = c->dstFormat; const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat); const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat); const int srcBpp = (c->srcFormatBpp + 7) >> 3; const int dstBpp = (c->dstFormatBpp + 7) >> 3; rgbConvFn conv = findRgbConvFn(c); if (!conv) { av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n", av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat)); } else { const uint8_t *srcPtr = src[0]; uint8_t *dstPtr = dst[0]; int src_bswap = IS_NOT_NE(c->srcFormatBpp, desc_src); int dst_bswap = IS_NOT_NE(c->dstFormatBpp, desc_dst); if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(dstFormat)) srcPtr += ALT32_CORR; if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat)) dstPtr += ALT32_CORR; if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 && !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap) conv(srcPtr, dstPtr + dstStride[0] * srcSliceY, srcSliceH * srcStride[0]); else { int i, j; dstPtr += dstStride[0] * srcSliceY; for (i = 0; i < srcSliceH; i++) { if(src_bswap) { for(j=0; j<c->srcW; j++) ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]); conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp); }else conv(srcPtr, dstPtr, c->srcW * srcBpp); if(dst_bswap) for(j=0; j<c->srcW; j++) ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]); srcPtr += srcStride[0]; dstPtr += dstStride[0]; } } } return srcSliceH; }
int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, int max_size) { uint32_t mrk; int i, tmp; const uint16_t *ssrc = (const uint16_t *) src; uint16_t *sdst = (uint16_t *) dst; PutBitContext pb; if ((unsigned) src_size > (unsigned) max_size) src_size = max_size; mrk = AV_RB32(src); switch (mrk) { case DCA_MARKER_RAW_BE: memcpy(dst, src, src_size); return src_size; case DCA_MARKER_RAW_LE: for (i = 0; i < (src_size + 1) >> 1; i++) *sdst++ = av_bswap16(*ssrc++); return src_size; case DCA_MARKER_14B_BE: case DCA_MARKER_14B_LE: init_put_bits(&pb, dst, max_size); for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; put_bits(&pb, 14, tmp); } flush_put_bits(&pb); return (put_bits_count(&pb) + 7) >> 3; default: return AVERROR_INVALIDDATA; } }
// Copy of ff_spdif_bswap_buf16, which sadly is a private symbol void lav_spdif_bswap_buf16(uint16_t *dst, const uint16_t *src, int w) { int i; for (i = 0; i + 8 <= w; i += 8) { dst[i + 0] = av_bswap16(src[i + 0]); dst[i + 1] = av_bswap16(src[i + 1]); dst[i + 2] = av_bswap16(src[i + 2]); dst[i + 3] = av_bswap16(src[i + 3]); dst[i + 4] = av_bswap16(src[i + 4]); dst[i + 5] = av_bswap16(src[i + 5]); dst[i + 6] = av_bswap16(src[i + 6]); dst[i + 7] = av_bswap16(src[i + 7]); } for (; i < w; i++) dst[i + 0] = av_bswap16(src[i + 0]); }
static int packed_16bpc_bswap(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]) { int i, j; int srcstr = srcStride[0] >> 1; int dststr = dstStride[0] >> 1; uint16_t *dstPtr = (uint16_t *) dst[0]; const uint16_t *srcPtr = (const uint16_t *) src[0]; int min_stride = FFMIN(srcstr, dststr); for (i = 0; i < srcSliceH; i++) { for (j = 0; j < min_stride; j++) { dstPtr[j] = av_bswap16(srcPtr[j]); } srcPtr += srcstr; dstPtr += dststr; } return srcSliceH; }
/** * Decode Smacker audio data */ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; HuffContext h[4] = { { 0 } }; VLC vlc[4] = { { 0 } }; int16_t *samples; uint8_t *samples8; int val; int i, res, ret; int unp_size; int bits, stereo; int pred[2] = {0, 0}; if (buf_size <= 4) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } unp_size = AV_RL32(buf); if (unp_size > (1U<<24)) { av_log(avctx, AV_LOG_ERROR, "packet is too big\n"); return AVERROR_INVALIDDATA; } if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0) return ret; if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *got_frame_ptr = 0; return 1; } stereo = get_bits1(&gb); bits = get_bits1(&gb); if (stereo ^ (avctx->channels != 1)) { av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); } if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) { av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } /* get output buffer */ frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); if (unp_size % (avctx->channels * (bits + 1))) { av_log(avctx, AV_LOG_ERROR, "unp_size %d is odd\n", unp_size); return AVERROR(EINVAL); } if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (int16_t *)frame->data[0]; samples8 = frame->data[0]; // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { h[i].length = 256; h[i].maxlength = 0; h[i].current = 0; h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); if (!h[i].bits || !h[i].lengths || !h[i].values) { ret = AVERROR(ENOMEM); goto error; } skip_bits1(&gb); if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { ret = AVERROR_INVALIDDATA; goto error; } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); ret = AVERROR_INVALIDDATA; goto error; } } } /* this codec relies on wraparound instead of clipping audio */ if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(get_bits_left(&gb)<0) return AVERROR_INVALIDDATA; if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val = h[2].values[res]; if(vlc[3].table) res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); *samples++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val = h[0].values[res]; if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); *samples++ = pred[0]; } } } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(get_bits_left(&gb)<0) return AVERROR_INVALIDDATA; if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } pred[1] += sign_extend(h[1].values[res], 8); *samples8++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; if (res < 0) { av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); return AVERROR_INVALIDDATA; } pred[0] += sign_extend(h[0].values[res], 8); *samples8++ = pred[0]; } } } *got_frame_ptr = 1; ret = buf_size; error: for(i = 0; i < 4; i++) { if(vlc[i].table) ff_free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); } return ret; }
int main() { int derp; FILE *file = NULL; char str[33]; char str2[33]; uint64_t fsize; uint8_t left; uint32_t frames; file = fopen("sola OP1.dvi", "rb"); fseek(file, 0L, SEEK_END); fsize = ftell(file); fseek(file, 0L, SEEK_SET); left = fsize % 16; frames = fsize / 16; snprintf(str, sizeof str, "%" PRIu64, fsize); printf( "File size: %s\n", str ); snprintf(str, sizeof str, "%" PRIu8, left); printf( "Left: %s\n", str ); snprintf(str, sizeof str, "%" PRIu32, frames); printf( "Amount of frames: %s\n\n", str ); frame_index index[frames]; for( uint32_t i = 0; i < frames; i++ ) { derp = fread( &index[i].offset, sizeof(uint32_t), 1, file ); if( derp != 1 ) { printf( "Derped\n" ); return 1; } index[i].offset = av_bswap32(index[i].offset); index[i].offset *= 4096; derp = fread( &index[i].size, sizeof(uint16_t), 1, file ); if( derp != 1 ) { printf( "Derped\n" ); return 1; } index[i].size = av_bswap16(index[i].size); index[i].size *= 4096; derp = fread( &index[i].frames_until_earlier, sizeof(uint16_t)+sizeof(uint32_t), 1, file ); if( derp != 1 ) { printf( "Derped\n" ); return 1; } index[i].frames_until_earlier = av_bswap64(index[i].frames_until_earlier); derp = fread( &index[i].aframe_count, sizeof(uint16_t), 1, file ); if( derp != 1 ) { printf( "Derped\n" ); return 1; } index[i].aframe_count = av_bswap16(index[i].aframe_count); derp = fread( &index[i].quality, sizeof(uint8_t), 1, file ); if( derp != 1 ) { printf( "Derped\n" ); return 1; } derp = fread( &index[i].reserved, sizeof(uint8_t), 1, file ); if( derp != 1 ) { printf( "Derped\n" ); return 1; } // snprintf(str2, sizeof str2, "%" PRIu32, i); // snprintf(str, sizeof str, "%" PRIu64, index[i].offset); // printf( "[frame %s] : Offset %s\n", str2, str ); // snprintf(str, sizeof str, "%" PRIu16, index[i].size); // printf( "[frame %s] : Size: %s\n", str2, str ); // snprintf(str, sizeof str, "%" PRIu64, index[i].frames_until_earlier); // printf( "[frame %s] : FuE: %s\n", str2, str ); // snprintf(str, sizeof str, "%" PRIu16, index[i].aframe_count); // printf( "[frame %s] : Amount of AFrames: %s\n", str2, str ); // snprintf(str, sizeof str, "%" PRIu8, index[i].quality); // printf( "[frame %s] : Quality: %s\n", str2, str ); } fclose(file); return 0; }
/** * Decode Smacker audio data */ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { SmackerAudioContext *s = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; HuffContext h[4] = { { 0 } }; VLC vlc[4] = { { 0 } }; int16_t *samples; uint8_t *samples8; int val; int i, res, ret; int unp_size; int bits, stereo; int pred[2] = {0, 0}; if (buf_size <= 4) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } unp_size = AV_RL32(buf); init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *got_frame_ptr = 0; return 1; } stereo = get_bits1(&gb); bits = get_bits1(&gb); if (stereo ^ (avctx->channels != 1)) { av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); return AVERROR(EINVAL); } if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) { av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); return AVERROR(EINVAL); } /* get output buffer */ s->frame.nb_samples = unp_size / (avctx->channels * (bits + 1)); if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } samples = (int16_t *)s->frame.data[0]; samples8 = s->frame.data[0]; // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { h[i].length = 256; h[i].maxlength = 0; h[i].current = 0; h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); smacker_decode_tree(&gb, &h[i], 0, 0); skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); return -1; } } } if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); else res = 0; val = h[2].values[res]; if(vlc[3].table) res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); else res = 0; val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); *samples++ = av_clip_int16(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; val = h[0].values[res]; if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); *samples++ = av_clip_int16(pred[0]); } } } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; pred[1] += sign_extend(h[1].values[res], 8); *samples8++ = av_clip_uint8(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; pred[0] += sign_extend(h[0].values[res], 8); *samples8++ = av_clip_uint8(pred[0]); } } } for(i = 0; i < 4; i++) { if(vlc[i].table) ff_free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); } *got_frame_ptr = 1; *(AVFrame *)data = s->frame; return buf_size; }
static void bswap16_buf(uint16_t *dst, const uint16_t *src, int count) { int i; for (i=0; i<count; i++) dst[i] = av_bswap16(src[i]); }
/** * Decode Smacker audio data */ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; GetBitContext gb; HuffContext h[4]; VLC vlc[4]; int16_t *samples = data; int8_t *samples8 = data; int val; int i, res; int unp_size; int bits, stereo; int pred[2] = {0, 0}; unp_size = AV_RL32(buf); init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); if(!get_bits1(&gb)){ av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); *data_size = 0; return 1; } stereo = get_bits1(&gb); bits = get_bits1(&gb); if (unp_size & 0xC0000000 || unp_size > *data_size) { av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); return -1; } memset(vlc, 0, sizeof(VLC) * 4); memset(h, 0, sizeof(HuffContext) * 4); // Initialize for(i = 0; i < (1 << (bits + stereo)); i++) { h[i].length = 256; h[i].maxlength = 0; h[i].current = 0; h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); smacker_decode_tree(&gb, &h[i], 0, 0); skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); if(res < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); return -1; } } } if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) pred[i] = av_bswap16(get_bits(&gb, 16)); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); else res = 0; val = h[2].values[res]; if(vlc[3].table) res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); else res = 0; val |= h[3].values[res] << 8; pred[1] += (int16_t)val; *samples++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; val = h[0].values[res]; if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; val |= h[1].values[res] << 8; pred[0] += val; *samples++ = pred[0]; } } } else { //8-bit data for(i = stereo; i >= 0; i--) pred[i] = get_bits(&gb, 8); for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; pred[1] += (int8_t)h[1].values[res]; *samples8++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; pred[0] += (int8_t)h[0].values[res]; *samples8++ = pred[0]; } } } for(i = 0; i < 4; i++) { if(vlc[i].table) free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); } *data_size = unp_size; return buf_size; }
static void swap_16(uint16_t *ptr, size_t size) { for (size_t n = 0; n < size; n++) ptr[n] = av_bswap16(ptr[n]); }
static void bswap16_buf(uint16_t *dst, const uint16_t *src, int len) { while (len--) *dst++ = av_bswap16(*src++); }