From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 36B724BFCE for ; Fri, 19 Jul 2024 23:54:59 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E1BD668D8A4; Sat, 20 Jul 2024 02:54:56 +0300 (EEST) Received: from mx.sdf.org (mx.sdf.org [205.166.94.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E764368B225 for ; Sat, 20 Jul 2024 02:54:49 +0300 (EEST) Received: from 9e5d27e4b9fe9ef6ae1fbb02e4373de4 ([1.145.217.137]) (authenticated (0 bits)) by mx.sdf.org (8.16.1/8.14.3) with ESMTPSA id 46JNsgtV026383 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits) verified NO) for ; Fri, 19 Jul 2024 23:54:46 GMT Date: Sat, 20 Jul 2024 09:54:37 +1000 From: Peter Ross To: FFmpeg development discussions and patches Message-ID: Mail-Followup-To: FFmpeg development discussions and patches References: MIME-Version: 1.0 In-Reply-To: Subject: Re: [FFmpeg-devel] Mono ADPCM for EA WVE Files / Fix Framerate X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: multipart/mixed; boundary="===============4519496143450276058==" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: --===============4519496143450276058== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ieNkBUau7OzrieD1" Content-Disposition: inline --ieNkBUau7OzrieD1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Jul 19, 2024 at 07:34:18AM -0400, redacted redacted wrote: > Hello there, >=20 > The Sims 1: Unleashed makes use of WVE files for its intro videos. > Two of the files for the game use Mono ADPCM audio instead of Stereo. > However, FFmpeg's ADPCM_EA codec always expects the files to be in Stereo. can you post a sample file somewhere > In addition, they're supposed to play at 30 fps, but the EA demuxer assum= es > 15 by default. > It appears the framerate is set with the use of the 0x1B code in the SCHl= / > PT00 header. nice find > I have made changes in the patch attached to fix these problems. thx for sharing. the patch needs a small amount of improvement. see below for my suggestions. > From 306f9db010cf000eb8477aca243fc970f5b95df8 Mon Sep 17 00:00:00 2001 > From: aaron > Date: Fri, 19 Jul 2024 07:30:10 -0400 > Subject: [PATCH 1/1] Mono ADPCM for EA WVE Files / Fix Framerate >=20 > --- > libavcodec/adpcm.c | 57 +++++++++++++++++++++++++----------- > libavformat/electronicarts.c | 12 ++++++-- > 2 files changed, 50 insertions(+), 19 deletions(-) >=20 > diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c > index f63afefd63..238214877d 100644 > --- a/libavcodec/adpcm.c > +++ b/libavcodec/adpcm.c > @@ -262,7 +262,7 @@ static av_cold int adpcm_decode_init(AVCodecContext *= avctx) > break; > case AV_CODEC_ID_ADPCM_DTK: > case AV_CODEC_ID_ADPCM_EA: > - min_channels =3D 2; > + min_channels =3D 1; > break; > case AV_CODEC_ID_ADPCM_AFC: > case AV_CODEC_ID_ADPCM_EA_R1: > @@ -914,10 +914,12 @@ static int get_nb_samples(AVCodecContext *avctx, Ge= tByteContext *gb, > bytestream2_seek(gb, -8, SEEK_CUR); > break; > case AV_CODEC_ID_ADPCM_EA: > + /* Stereo is 30 bytes per block */ > + /* Mono is 15 bytes per block */ > has_coded_samples =3D 1; > *coded_samples =3D bytestream2_get_le32(gb); > *coded_samples -=3D *coded_samples % 28; > - nb_samples =3D (buf_size - 12) / 30 * 28; > + nb_samples =3D (buf_size - 12) / (ch =3D=3D 2 ? 30 : 15) * = 28; > break; > case AV_CODEC_ID_ADPCM_IMA_EA_EACS: > has_coded_samples =3D 1; > @@ -1652,10 +1654,10 @@ static int adpcm_decode_frame(AVCodecContext *avc= tx, AVFrame *frame, > int coeff1l, coeff2l, coeff1r, coeff2r; > int shift_left, shift_right; > =20 > - /* Each EA ADPCM frame has a 12-byte header followed by 30-byte = pieces, > - each coding 28 stereo samples. */ > - > - if (channels !=3D 2) > + /* Each EA ADPCM frame has a 12-byte header followed by 30-byte = (stereo) or 15-byte (mono) pieces, > + each coding 28 stereo/mono samples. */ > + =20 > + if (channels !=3D 2 && channels !=3D 1) > return AVERROR_INVALIDDATA; > =20 > current_left_sample =3D sign_extend(bytestream2_get_le16u(&gb)= , 16); > @@ -1665,37 +1667,58 @@ static int adpcm_decode_frame(AVCodecContext *avc= tx, AVFrame *frame, > =20 > for (int count1 =3D 0; count1 < nb_samples / 28; count1++) { > int byte =3D bytestream2_get_byteu(&gb); > - coeff1l =3D ea_adpcm_table[ byte >> 4 ]; > - coeff2l =3D ea_adpcm_table[(byte >> 4 ) + 4]; > + coeff1l =3D ea_adpcm_table[ byte >> 4 ]; > + coeff2l =3D ea_adpcm_table[(byte >> 4) + 4]; these whitespace-only changes shouldn't go in the patch. > coeff1r =3D ea_adpcm_table[ byte & 0x0F]; > coeff2r =3D ea_adpcm_table[(byte & 0x0F) + 4]; > =20 > - byte =3D bytestream2_get_byteu(&gb); > - shift_left =3D 20 - (byte >> 4); > - shift_right =3D 20 - (byte & 0x0F); > - > - for (int count2 =3D 0; count2 < 28; count2++) { > + if (channels =3D=3D 2){ > + byte =3D bytestream2_get_byteu(&gb); > + shift_left =3D 20 - (byte >> 4); > + shift_right =3D 20 - (byte & 0x0F); > + } else{ > + /* Mono packs the shift into the coefficient byte's lowe= r nibble instead */ > + shift_left =3D 20 - (byte & 0x0F); > + } > + =20 > + for (int count2 =3D 0; count2 < ( channels =3D=3D 2 ? 28 : 1= 4); count2++) { "count2 < ( channels..." looks out of place. drop the space after the parenthesis. > byte =3D bytestream2_get_byteu(&gb); > next_left_sample =3D sign_extend(byte >> 4, 4) * (1 << = shift_left); > - next_right_sample =3D sign_extend(byte, 4) * (1 << = shift_right); > + next_right_sample =3D sign_extend(byte, 4) * (1 << shift= _right); > =20 > next_left_sample =3D (next_left_sample + > (current_left_sample * coeff1l) + > (previous_left_sample * coeff2l) + 0x80) >> 8; > + > next_right_sample =3D (next_right_sample + > (current_right_sample * coeff1r) + > (previous_right_sample * coeff2r) + 0x80) >> 8; > =20 > previous_left_sample =3D current_left_sample; > current_left_sample =3D av_clip_int16(next_left_sample); > + > previous_right_sample =3D current_right_sample; > current_right_sample =3D av_clip_int16(next_right_sample= ); > + > *samples++ =3D current_left_sample; > - *samples++ =3D current_right_sample; > + ditto for these whitespace-only changes above. > + if (channels =3D=3D 2){ > + *samples++ =3D current_right_sample; > + } else { > + next_left_sample =3D sign_extend(byte, 4) * (1 << s= hift_left); > + > + next_left_sample =3D (next_left_sample + > + (current_left_sample * coeff1l) + > + (previous_left_sample * coeff2l) + 0x80) >> 8; > + > + previous_left_sample =3D current_left_sample; > + current_left_sample =3D av_clip_int16(next_left_samp= le); > + > + *samples++ =3D current_left_sample; > + } > } > } > - > - bytestream2_skip(&gb, 2); // Skip terminating 0x0000 > + bytestream2_skip(&gb, channels =3D=3D 2 ? 2 : 3); // Skip termin= ating NULs > ) /* End of CASE */ > CASE(ADPCM_EA_MAXIS_XA, > int coeff[2][2], shift[2]; i suggest splitting this into two patches, one for mono adpcm ea, another f= or the frame rate fix. > diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c > index f7f6fd4cab..c141a172dd 100644 > --- a/libavformat/electronicarts.c > +++ b/libavformat/electronicarts.c > @@ -86,6 +86,8 @@ typedef struct EaDemuxContext { > enum AVCodecID audio_codec; > int audio_stream_index; > =20 > + int framerate; > + > int bytes; > int sample_rate; > int num_channels; > @@ -198,6 +200,10 @@ static int process_audio_header_elements(AVFormatCon= text *s) > av_log(s, AV_LOG_DEBUG, "end of header block reached\n"); > in_header =3D 0; > break; > + case 0x1B: > + ea->framerate =3D read_arbitrary(pb); > + av_log(s, AV_LOG_DEBUG, "Setting framerate to %u", ea->frame= rate); > + break; av_log trailing "\n" missing > default: > av_log(s, AV_LOG_DEBUG, > "header element 0x%02x set to 0x%08"PRIx32"\n", > @@ -367,6 +373,8 @@ static int process_ea_header(AVFormatContext *s) > AVIOContext *pb =3D s->pb; > int i; > =20 > + ea->framerate =3D 15; > + > for (i =3D 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) { > uint64_t startpos =3D avio_tell(pb); > int err =3D 0; > @@ -427,12 +435,12 @@ static int process_ea_header(AVFormatContext *s) > case pQGT_TAG: > case TGQs_TAG: > ea->video.codec =3D AV_CODEC_ID_TGQ; > - ea->video.time_base =3D (AVRational) { 1, 15 }; > + ea->video.time_base =3D (AVRational) { 1, ea->framerate }; > break; > =20 > case pIQT_TAG: > ea->video.codec =3D AV_CODEC_ID_TQI; > - ea->video.time_base =3D (AVRational) { 1, 15 }; > + ea->video.time_base =3D (AVRational) { 1, ea->framerate }; > break; > =20 > case MADk_TAG: > --=20 -- Peter (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B) --ieNkBUau7OzrieD1 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQSpB+AvpuUM0jTNINJnYHnFrEDdawUCZpr8uQAKCRBnYHnFrEDd a1vSAJ48T3IYlikXK2GF+DaHS+b+klPYAgCcC0gkJUl+ELZCJrsloCvkY7LRXCM= =veiQ -----END PGP SIGNATURE----- --ieNkBUau7OzrieD1-- --===============4519496143450276058== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". --===============4519496143450276058==--