pastebin - collaborative debugging tool
kpaste.net RSS


ffmeow
Posted by Anonymous on Sat 16th Aug 2025 02:57
raw | new post

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libavcodec/avcodec.h>
  4. #include <libavformat/avformat.h>
  5. #include <libavutil/avutil.h>
  6. #include <alsa/asoundlib.h>
  7.  
  8. int
  9. main(int argc, char *argv[])
  10. {
  11.         if (argc < 2) {
  12.                 fprintf(stderr, "argc\n");
  13.                 return 1;
  14.         }
  15.  
  16.         printf("[INFO] %s\n", argv[1]);
  17.  
  18.         snd_pcm_t *handle = NULL;
  19.         if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0)
  20.                 goto end_playback;
  21.  
  22.         struct AVFormatContext *formatContext = NULL;
  23.         if (avformat_open_input(&formatContext, argv[1], NULL, NULL) < 0)
  24.                 goto end_playback;
  25.  
  26.         if (avformat_find_stream_info(formatContext, NULL) < 0)
  27.                 goto end_playback;
  28.  
  29.         int streamId;
  30.         if ((streamId = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0)) < 0)
  31.                 goto end_playback;
  32.  
  33.         const struct AVCodec *codec = avcodec_find_decoder(formatContext->streams[streamId]->codecpar->codec_id);
  34.         if (!codec)
  35.                 goto end_playback;
  36.  
  37.         struct AVCodecContext *codecContext = avcodec_alloc_context3(codec);
  38.         if (!codecContext)
  39.                 goto end_playback;
  40.  
  41.         if (avcodec_parameters_to_context(codecContext, formatContext->streams[streamId]->codecpar))
  42.                 goto end_playback;
  43.  
  44.         if (avcodec_open2(codecContext, codec, NULL) < 0)
  45.                 goto end_playback;
  46.  
  47.  
  48.         snd_pcm_format_t alsaFormat;
  49.         switch (codecContext->sample_fmt)
  50.         {
  51.                 case AV_SAMPLE_FMT_S16P:
  52.                 case AV_SAMPLE_FMT_S16: alsaFormat = SND_PCM_FORMAT_S16_LE; break;
  53.                 case AV_SAMPLE_FMT_S32: alsaFormat = SND_PCM_FORMAT_S32_LE; break;
  54.                 case AV_SAMPLE_FMT_FLTP:
  55.                 case AV_SAMPLE_FMT_FLT: alsaFormat = SND_PCM_FORMAT_FLOAT_LE; break;
  56.                 case AV_SAMPLE_FMT_U8:  alsaFormat = SND_PCM_FORMAT_U8; break;
  57.                 default:
  58.                         goto end_playback;
  59.         }
  60.  
  61.         if (snd_pcm_set_params(handle,
  62.                         alsaFormat,
  63.                         SND_PCM_ACCESS_RW_INTERLEAVED,
  64.                         formatContext->streams[streamId]->codecpar->ch_layout.nb_channels,
  65.                         codecContext->sample_rate,
  66.                         1, 500000) < 0)
  67.                 goto end_playback;
  68.  
  69.         AVPacket *packet = av_packet_alloc();
  70.         AVFrame *frame = av_frame_alloc();
  71.         if (!packet || !frame)
  72.                 goto end_playback;
  73.  
  74.         while (av_read_frame(formatContext, packet) >= 0) {
  75.                 if (packet->stream_index != streamId)
  76.                         continue;
  77.                 if (avcodec_send_packet(codecContext, packet) != 0) {
  78.                         av_packet_unref(packet);
  79.                         break;
  80.                 }
  81.  
  82.                 while (!avcodec_receive_frame(codecContext, frame)) {
  83.                         uint8_t *audioData = NULL;
  84.                         uint8_t *audioDataPtr = NULL;
  85.                         int channels = formatContext->streams[streamId]->codecpar->ch_layout.nb_channels;
  86.                         int sampleSize = av_get_bytes_per_sample(frame->format);
  87.                         snd_pcm_sframes_t frames = frame->nb_samples;
  88.  
  89.                         if (av_sample_fmt_is_planar(frame->format)) {
  90.                                 audioData = malloc(channels * frame->nb_samples * sampleSize);
  91.                                 float *dst = (float *)audioData;
  92.  
  93.                                 for (int i = 0; i < frame->nb_samples; i++) {
  94.                                         for (int ch = 0; ch < channels; ch++) {
  95.                                                 float *src = (float *)frame->data[ch];
  96.                                                 dst[i * channels + ch] = src[i];
  97.                                         }
  98.                                 }
  99.                                 audioDataPtr = audioData;
  100.  
  101.                         } else {
  102.                                 audioData = frame->data[0];
  103.                                 audioDataPtr = audioData;
  104.                         }
  105.  
  106.                         while (frames > 0) {
  107.                                 snd_pcm_sframes_t written = snd_pcm_writei(handle, audioData, frames);
  108.                                 if (written < 0) {
  109.                                         if (written == -EAGAIN)
  110.                                                 continue;
  111.                                         if (av_sample_fmt_is_planar(frame->format))
  112.                                                 free(audioData);
  113.  
  114.                                         goto end_playback;
  115.                                 } else {
  116.                                         frames -= written;
  117.                                         audioDataPtr += written * sampleSize * channels;
  118.                                 }
  119.  
  120.                                 if (written < 0 && written != -EAGAIN)
  121.                                         goto end_playback;
  122.                         }
  123.  
  124.                         if (av_sample_fmt_is_planar(frame->format))
  125.                                 free(audioData);
  126.                         av_frame_unref(frame);
  127.                 }
  128.  
  129.                 av_packet_unref(packet);
  130.         }
  131.  
  132. end_playback:
  133.         if (packet)
  134.                 av_packet_free(&packet);
  135.         if (frame)
  136.                 av_frame_free(&frame);
  137.         if (codecContext)
  138.                 avcodec_free_context(&codecContext);
  139.         if (formatContext)
  140.                 avformat_close_input(&formatContext);
  141.         if (handle)
  142.                 snd_pcm_close(handle);
  143.  
  144.  
  145.         return 0;
  146. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at