Revel_Error Revel_BaseEncoder::EncodeAudio(const void *sampleBuffer, const int numBytes, int *numTotalBytes) { // Make sure it's safe to be encoding. if (!m_isEncoding) return REVEL_ERR_BUSY; if (m_params.hasAudio != 1) return REVEL_ERR_NONE; // Check args if (numBytes == 0) return REVEL_ERR_NONE; if (sampleBuffer == NULL) return REVEL_ERR_PARAMS; int err = AVI_write_audio(m_outFile, (char*)sampleBuffer, numBytes); if (err != 0) return REVEL_ERR_FILE; m_totalOutBytes += numBytes; if (numTotalBytes != NULL) *numTotalBytes = AVI_audio_bytes(m_outFile); return REVEL_ERR_NONE; }
bool CAviAudioByteStream::start_next_frame (uint8_t **buffer, uint32_t *buflen, frame_timestamp_t *ts, void **ud) { int value; if (m_buffer_on < m_this_frame_size) { value = m_this_frame_size - m_buffer_on; memmove(m_buffer, m_buffer + m_buffer_on, m_this_frame_size - m_buffer_on); m_this_frame_size -= m_buffer_on; } else { value = 0; m_this_frame_size = 0; } m_buffer_on = 0; m_parent->lock_file_mutex(); AVI_set_audio_position(m_parent->get_file(), m_file_pos); int ret; ret = AVI_read_audio(m_parent->get_file(), (char *)m_buffer + value, m_max_frame_size - m_this_frame_size); m_parent->unlock_file_mutex(); //player_debug_message("return from avi read %d", ret); m_this_frame_size += ret; m_file_pos += ret; if (m_file_pos >= AVI_audio_bytes(m_parent->get_file())) { m_eof = 1; } *buffer = m_buffer; *buflen = m_this_frame_size; #if 0 uint64_t ret; ret = m_frame_on; ret *= m_samples_per_frame; ret *= 1000; ret /= m_frame_rate; player_debug_message("Start next frame "U64 " offset %u %u", ret, m_byte_on, m_this_frame_size); return (ret); #endif ts->msec_timestamp = 0; ts->audio_freq_timestamp = 0; ts->audio_freq = AVI_audio_rate(m_parent->get_file()); ts->timestamp_is_pts = false; return true; }
void AVI_info(avi_t *avifile) { long frames, rate, mp3rate, chunks, tot_bytes; int width, height, format, chan, bits; int j, tracks, tmp; double fps; char *codec; frames = AVI_video_frames(avifile); width = AVI_video_width(avifile); height = AVI_video_height(avifile); fps = AVI_frame_rate(avifile); codec = AVI_video_compressor(avifile); printf("[avilib] V: %6.3f fps, codec=%s, frames=%ld, width=%d, height=%d\n", fps, ((strlen(codec)==0)? "RGB": codec), frames, width, height); tracks=AVI_audio_tracks(avifile); tmp=AVI_get_audio_track(avifile); for(j=0; j<tracks; ++j) { AVI_set_audio_track(avifile, j); rate = AVI_audio_rate(avifile); format = AVI_audio_format(avifile); chan = AVI_audio_channels(avifile); bits = AVI_audio_bits(avifile); mp3rate= AVI_audio_mp3rate(avifile); chunks = AVI_audio_chunks(avifile); tot_bytes = AVI_audio_bytes(avifile); if(chan>0) { printf("[avilib] A: %ld Hz, format=0x%02x, bits=%d, channels=%d, bitrate=%ld kbps,\n", rate, format, bits, chan, mp3rate); printf("[avilib] %ld chunks, %ld bytes, %s\n", chunks, tot_bytes, (AVI_get_audio_vbr(avifile)?"VBR":"CBR")); } else printf("[avilib] A: no audio track found\n"); } AVI_set_audio_track(avifile, tmp); //reset }
/* * avi2raw * required arg1 should be the input AVI file * required arg2 should be the output RAW file */ int main(int argc, char** argv) { /* configurable variables from command line */ bool extractVideo = TRUE; /* FALSE implies extract audio */ u_int32_t start = 0; /* secs, start offset */ u_int32_t duration = 0; /* secs, 0 implies entire file */ bool quiet = FALSE; /* internal variables */ char* aviFileName = NULL; char* rawFileName = NULL; avi_t* aviFile = NULL; FILE* rawFile = NULL; int verbose = FALSE; u_int32_t numBytes, totBytes = 0; bool eliminate_short_frames = FALSE; uint32_t short_frames_len; /* begin process command line */ progName = argv[0]; while (1) { int c = -1; int option_index = 0; static struct option long_options[] = { { "audio", 0, 0, 'a' }, { "eliminate-short-frames", optional_argument, 0, 'e'}, { "length", 1, 0, 'l' }, { "quiet", 0, 0, 'q' }, { "start", 1, 0, 's' }, { "video", 0, 0, 'v' }, { "version", 0, 0, 'V'}, { "verbose", 0, 0, 'R'}, { "help", 0, 0, 'h'}, { NULL, 0, 0, 0 } }; c = getopt_long_only(argc, argv, "ael:qs:vVh", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': fprintf(stderr, "%s - %s version %s\n", progName, MPEG4IP_PACKAGE, MPEG4IP_VERSION); fprintf(stderr, "options:\n"); fprintf(stderr, " --audio - extract audio track\n"); fprintf(stderr, " --length <length> - extract <length> secs\n"); fprintf(stderr, " --quiet - quiet mode\n"); fprintf(stderr, " --start <time> - extract from <start> time\n"); fprintf(stderr, " --video - extract video track\n"); fprintf(stderr, " --eliminate-short-frames <bytes> - eliminate short frames of bytes or less - default 4\n"); return 0; case 'a': { extractVideo = FALSE; break; } case 'e': eliminate_short_frames = TRUE; if (optarg) { if (optarg[0] == '=') optarg[0] = ' '; if (sscanf(optarg, "%u", &short_frames_len) != 1) { fprintf(stderr, "%s:bad eliminate length %s\n", progName, optarg); } } else { short_frames_len = 4; } break; case 'l': { /* --length=<secs> */ u_int i; if (sscanf(optarg, "%u", &i) < 1) { fprintf(stderr, "%s: bad length specified: %s\n", progName, optarg); } else { duration = i; } break; } case 'q': { quiet = TRUE; break; } case 's': { /* --start=<secs> */ u_int i; if (sscanf(optarg, "%u", &i) < 1) { fprintf(stderr, "%s: bad start specified: %s\n", progName, optarg); } else { start = i; } break; } case 'v': { extractVideo = TRUE; break; } case '?': break; case 'R': verbose = TRUE; quiet = FALSE; break; case 'V': fprintf(stderr, "%s - %s version %s\n", progName, MPEG4IP_PACKAGE, MPEG4IP_VERSION); return(0); default: fprintf(stderr, "%s: unknown option specified, ignoring: %c\n", progName, c); } } /* check that we have at least two non-option arguments */ if ((argc - optind) < 2) { fprintf(stderr, "usage: %s <avi-file> <raw-file>\n", progName); exit(1); } /* point to the specified file names */ aviFileName = argv[optind++]; rawFileName = argv[optind++]; /* warn about extraneous non-option arguments */ if (optind < argc) { fprintf(stderr, "%s: unknown options specified, ignoring: ", progName); while (optind < argc) { fprintf(stderr, "%s ", argv[optind++]); } fprintf(stderr, "\n"); } /* end processing of command line */ /* open the AVI file */ aviFile = AVI_open_input_file(aviFileName, TRUE); if (aviFile == NULL) { fprintf(stderr, "%s: error %s: %s\n", progName, aviFileName, AVI_strerror()); exit(4); } if (!quiet) { fprintf(stderr, "%s - %s version %s\n", progName, MPEG4IP_PACKAGE, MPEG4IP_VERSION); } /* open the RAW file */ rawFile = fopen(rawFileName, "wb"); if (rawFile == NULL) { fprintf(stderr, "%s: error opening %s: %s\n", progName, rawFileName, strerror(errno)); exit(5); } if (extractVideo) { double videoFrameRate = AVI_video_frame_rate(aviFile); u_int32_t numVideoFrames = AVI_video_frames(aviFile); u_int32_t fileDuration = ceil(numVideoFrames / videoFrameRate); u_int32_t numDesiredVideoFrames; u_int32_t videoFramesRead = 0; u_int32_t emptyFramesRead = 0; /* get a buffer large enough to handle a frame of raw SDTV */ u_char* buf = (u_char*)malloc(768 * 576 * 4); if (duration) { numDesiredVideoFrames = duration * videoFrameRate; } else { numDesiredVideoFrames = numVideoFrames; } if (buf == NULL) { fprintf(stderr, "%s: error allocating memory: %s\n", progName, strerror(errno)); exit(6); } /* check that start offset is valid */ if (start > fileDuration) { fprintf(stderr, "%s: specified start is past the end of the file\n", progName); exit(7); } if (AVI_seek_start(aviFile)) { fprintf(stderr, "%s: bad seek: %s\n", progName, AVI_strerror()); exit(8); } if (AVI_set_video_position(aviFile, (long) ROUND(start * videoFrameRate), NULL)) { fprintf(stderr, "%s: bad seek: %s\n", progName, AVI_strerror()); exit(9); } #ifdef DEBUG_H264 h264_decode_t dec; #endif while (TRUE) { numBytes = AVI_read_frame(aviFile, (char *)buf); /* read error */ if (numBytes < 0) { break; } totBytes += numBytes; videoFramesRead++; if (verbose) { printf("frame %d - len %u total %u\n", videoFramesRead, numBytes, totBytes); } /* * note some capture programs * insert a zero length frame occasionally * hence numBytes == 0, but we're not a EOF */ if ((eliminate_short_frames && numBytes > short_frames_len) || (eliminate_short_frames == FALSE && numBytes)) { // test #ifdef DEBUG_H264 uint32_t offset = 0, read; do { if (h264_is_start_code(buf + offset)) { int ret = h264_detect_boundary(buf + offset, numBytes - offset, &dec); printf(" frame offset %d nal type %d slice %d %d\n", offset, dec.nal_unit_type, dec.slice_type, ret); } read = h264_find_next_start_code(buf + offset, numBytes - offset); offset += read; } while (read != 0 && offset < numBytes); #endif if (fwrite(buf, 1, numBytes, rawFile) != numBytes) { fprintf(stderr, "%s: error writing %s: %s\n", progName, rawFileName, strerror(errno)); break; } } else { emptyFramesRead++; } if (videoFramesRead >= numDesiredVideoFrames) { break; } } if (verbose) { printf("read %u video bytes\n", totBytes); } if (numBytes < 0) { printf("%s: error reading %s, frame %d, %s\n", progName, aviFileName, videoFramesRead + 1, AVI_strerror()); } if (videoFramesRead < numDesiredVideoFrames) { fprintf(stderr, "%s: warning: could only extract %u seconds of video (%u of %u frames)\n", progName, (unsigned int)ceil(videoFramesRead / videoFrameRate), videoFramesRead, numDesiredVideoFrames); } if (emptyFramesRead) { fprintf(stderr, "%s: warning: %u zero length frames ignored\n", progName, emptyFramesRead); } if (!quiet) { printf("%u video frames written\n", videoFramesRead - emptyFramesRead); } /* cleanup */ free(buf); } else { /* extract audio */ u_int32_t audioBytesRead = 0; u_char *buf = (u_char*) malloc(8*1024); u_int32_t numDesiredAudioBytes = AVI_audio_bytes(aviFile); u_int32_t audioBytesPerSec = 0; if (start != 0) { u_int32_t numAudioBytes = numDesiredAudioBytes; u_int32_t fileDuration; audioBytesPerSec = AVI_audio_rate(aviFile) * ((AVI_audio_bits(aviFile) + 7) / 8) * AVI_audio_channels(aviFile); fileDuration = ceil(numAudioBytes / audioBytesPerSec); numDesiredAudioBytes = duration * audioBytesPerSec; /* check that start offset is valid */ if (start > fileDuration) { fprintf(stderr, "%s: specified start is past the end of the file\n", progName); exit(7); } if (AVI_seek_start(aviFile)) { fprintf(stderr, "%s: bad seek: %s\n", progName, AVI_strerror()); exit(8); } if (AVI_set_audio_position(aviFile, start * audioBytesPerSec)) { fprintf(stderr, "%s: bad seek: %s\n", progName, AVI_strerror()); exit(9); } } else { if (AVI_seek_start(aviFile)) { fprintf(stderr, "%s: bad seek: %s\n", progName, AVI_strerror()); exit(8); } if (AVI_set_audio_position(aviFile, 0)) { fprintf(stderr, "%s: bad seek: %s\n", progName, AVI_strerror()); exit(9); } } while ((numBytes = AVI_read_audio(aviFile, (char *)buf, sizeof(buf))) > 0) { if (fwrite(buf, 1, numBytes, rawFile) != numBytes) { fprintf(stderr, "%s: error writing %s: %s\n", progName, rawFileName, strerror(errno)); break; } audioBytesRead += numBytes; if (numDesiredAudioBytes && audioBytesRead >= numDesiredAudioBytes) { break; } } if (verbose) { printf("read %u audio bytes\n", audioBytesRead); } if (duration && audioBytesRead < numDesiredAudioBytes) { fprintf(stderr, "%s: warning: could only extract %u seconds of audio\n", progName, audioBytesPerSec == 0 ? audioBytesRead : audioBytesRead / audioBytesPerSec); } if (!quiet && AVI_audio_bits(aviFile) != 0) { printf("%u audio samples written\n", audioBytesRead / ((AVI_audio_bits(aviFile) + 7) / 8)); } } /* cleanup */ AVI_close(aviFile); fclose(rawFile); return(0); }
/* * Create the media for the quicktime file, and set up some session stuff. */ int create_media_for_avi_file (CPlayerSession *psptr, const char *name, char *errmsg, uint32_t errlen, int have_audio_driver, control_callback_vft_t *cc_vft) { CAviFile *Avifile1 = NULL; avi_t *avi; CPlayerMedia *mptr; avi = AVI_open_input_file(name, 1); if (avi == NULL) { snprintf(errmsg, errlen, "%s", AVI_strerror()); player_error_message("%s", AVI_strerror()); return (-1); } int video_count = 1; codec_plugin_t *plugin; video_query_t vq; const char *codec_name = AVI_video_compressor(avi); player_debug_message("Trying avi video codec %s", codec_name); plugin = check_for_video_codec(STREAM_TYPE_AVI_FILE, codec_name, NULL, -1, -1, NULL, 0, &config); if (plugin == NULL) { video_count = 0; } else { vq.track_id = 1; vq.stream_type = STREAM_TYPE_AVI_FILE; vq.compressor = codec_name; vq.type = -1; vq.profile = -1; vq.fptr = NULL; vq.h = AVI_video_height(avi); vq.w = AVI_video_width(avi); vq.frame_rate = AVI_video_frame_rate(avi); vq.config = NULL; vq.config_len = 0; vq.enabled = 0; vq.reference = NULL; } int have_audio = 0; int audio_count = 0; audio_query_t aq; if (AVI_audio_bytes(avi) != 0) { have_audio = 1; plugin = check_for_audio_codec(STREAM_TYPE_AVI_FILE, NULL, NULL, AVI_audio_format(avi), -1, NULL, 0, &config); if (plugin != NULL) { audio_count = 1; aq.track_id = 1; aq.stream_type = STREAM_TYPE_AVI_FILE; aq.compressor = NULL; aq.type = AVI_audio_format(avi); aq.profile = -1; aq.fptr = NULL; aq.sampling_freq = AVI_audio_rate(avi); aq.chans = AVI_audio_channels(avi); aq.config = NULL; aq.config_len = 0; aq.enabled = 0; aq.reference = NULL; } } if (cc_vft != NULL && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_count, &vq, audio_count, &aq); } else { if (video_count != 0) vq.enabled = 1; if (audio_count != 0) aq.enabled = 1; } if ((video_count == 0 || vq.enabled == 0) && (audio_count == 0 || aq.enabled == 0)) { snprintf(errmsg, errlen, "No audio or video tracks enabled or playable"); AVI_close(avi); return -1; } Avifile1 = new CAviFile(name, avi, vq.enabled, audio_count); psptr->set_media_close_callback(close_avi_file, Avifile1); if (video_count != 0 && vq.enabled) { mptr = new CPlayerMedia(psptr); if (mptr == NULL) { return (-1); } video_info_t *vinfo = MALLOC_STRUCTURE(video_info_t); if (vinfo == NULL) return (-1); vinfo->height = vq.h; vinfo->width = vq.w; player_debug_message("avi file h %d w %d frame rate %g", vinfo->height, vinfo->width, vq.frame_rate); plugin = check_for_video_codec(STREAM_TYPE_AVI_FILE, codec_name, NULL, -1, -1, NULL, 0, &config); int ret; ret = mptr->create_video_plugin(plugin, STREAM_TYPE_AVI_FILE, codec_name, -1, -1, NULL, vinfo, NULL, 0); if (ret < 0) { snprintf(errmsg, errlen, "Failed to create video plugin %s", codec_name); player_error_message("Failed to create plugin data"); delete mptr; return -1; } CAviVideoByteStream *vbyte = new CAviVideoByteStream(Avifile1); if (vbyte == NULL) { delete mptr; return (-1); } vbyte->config(AVI_video_frames(avi), vq.frame_rate); ret = mptr->create(vbyte, TRUE, errmsg, errlen); if (ret != 0) { return (-1); } } int seekable = 1; if (have_audio_driver > 0 && audio_count > 0 && aq.enabled != 0) { plugin = check_for_audio_codec(STREAM_TYPE_AVI_FILE, NULL, NULL, aq.type, -1, NULL, 0, &config); CAviAudioByteStream *abyte; mptr = new CPlayerMedia(psptr); if (mptr == NULL) { return (-1); } audio_info_t *ainfo; ainfo = MALLOC_STRUCTURE(audio_info_t); ainfo->freq = aq.sampling_freq; ainfo->chans = aq.chans; ainfo->bitspersample = AVI_audio_bits(avi); int ret; ret = mptr->create_audio_plugin(plugin, aq.stream_type, aq.compressor, aq.type, aq.profile, NULL, ainfo, NULL, 0); if (ret < 0) { delete mptr; player_error_message("Couldn't create audio from plugin %s", plugin->c_name); return -1; } abyte = new CAviAudioByteStream(Avifile1); ret = mptr->create(abyte, FALSE, errmsg, errlen); if (ret != 0) { return (-1); } seekable = 0; } psptr->session_set_seekable(seekable); if (audio_count == 0 && have_audio != 0) { snprintf(errmsg, errlen, "Unknown Audio Codec in avi file "); return (1); } if (video_count != 1) { snprintf(errmsg, errlen, "Unknown Video Codec %s in avi file", codec_name); return (1); } return (0); }